一、 山重水复疑无路

六个实际问题的困惑

大系统架构设计,如何开始?

总觉得需求不清晰,影响架构设计!

非功能需求重要,但如何设计?

将系统划分模块,如何更合理?

架构设计如何,哪些没考虑到,心里没底

想用新技术,纠结

两个职业发展的困惑

缺乏指导,不知所措,老司机,谁能带带我

缺乏总结,仍对下一个项目心虚

写这系列的文章,来逐步解决上面的困惑。

二、软件架构是什么?

对于软件架构的定义,仁者见仁,智者见智。目前,业界比较流行的两大流派是组成派和决策派,这两派的概念相辅相成,具体如下:

组成派:软件架构 = 组件 + 交互。

决策派:软件架构 = 重要决策集。

上述两大流派的描述过于抽象,不利于理解,本人更喜欢下述关于软件架构的描述,通俗易懂。

1.软件架构是一个系统的草图。

 2.软件架构描述的对象是直接构成系统的抽象组件。

 3.各个组件之间的连接则明确和相对细致地描述组件之间的通讯。

 4.在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。

 5.在面向对象领域中,组件之间的连接通常用接口来实现。

从本质上讲,架构设计毫无疑问是需求驱动而非模型驱动的。还有的专家提倡的“用例驱动的架构设计”观点,其实存在着严重缺陷:
1.需求=功能+质量+约束
2.用例是功能需求的实际标准
3.用例不涉及非功能需求
三、软件架构的重要性

软件架构能够满足系统的品质
架构设计使受益人达成一致的目标
架构设计能够支持计划编制过程
架构设计对系统开发的指导性
架构设计能够有效地管理复杂性
架构设计为复用奠定了基础
架构设计能够降低维护费用
架构设计能够支持冲突分析
四、软件架构的目标

功能:功能上必须满足需求

高内聚低耦合:架构是恰如其分的

可靠性:软件系统必须非常可靠

可用性:系统必须可用

可维护性:一个易于维护的系统可以有效地降低技术支持的花费

安全性:系统的安全性非常重要

可扩展性:必须能够在用户的数目增加很快的情况下,保持合理的性能

五、架构设计的驱动力

何为驱动?通过本质规律去建模世界,才能以“一”推演万物。种种推演的过程,皆是要去寻找某种驱动力量作为分析或建构的起点。

何为“力”?所谓“力”,其实是一种隐喻。不同的影响因素会决定着架构师的设计决策,而这些决策之间又相互影响着,或者相吸,或者相斥,绝对不能孤立看待。

如何寻找架构驱动力呢?正如在《架构之美》中John Klein、David Weiss写道:

软件架构师的首要关注点不是系统的功能。……你关注的是需要满足的品质。品质关注点指明了功能必须以何种方式交付,才能被系统的利益相关人所接受,系统的结果包含这些人的既定利益。

于是,架构分析与设计就变成了对软件系统的影响力识别,这种设计的驱动力即我们所谓的RAID分析法。

六、RAID分析法

所谓RAID分析法,即识别软件系统的风险(Risk)、假设(Assumption)、问题(Issue)、依赖(Dependency),准确地说,就是

  1. 评估风险
    风险其实就是未来可能出现的问题。我们在软件设计的过程中,既要满足现实,却又需要预测未来,如何做到架构设计的恰如其分。
  2. 明确假设

我们往往会忽略为系统给定假设(Assumption),而事实上,这种假设往往代表了关键的架构约束。架构约束是一种非常重要的驱动力。Roy Fielding如此勾勒出约束的重要性:

属性是由架构中的一组约束所导致的。约束往往是由在架构元素的某个方面应用软件工程原则来驱动的。例如,统一管道和过滤器(uniform pipe-and-filter)风格通过在其组件接口之上应用通用性原则——强迫组件实现单一的接口类型,从应用中获得了组件的可重用性和可配置性的品质。因此,架构约束是由通用性原则所驱动的“统一组件接口”,目的是获得两个想要得到的品质,当在架构中实现了这种风格时,这两个品质将成为可重用和可配置组件的架构属性。

我们在明确假设时,需要将这些约束甄别出来,以之作为架构设计的驱动力。

3.分析问题

分析现在存在的问题,评估未来风险。

4.识别依赖

如何分解(内聚),如何协作(耦合),这就是我们需要遵循的高内聚低耦合设计原则。

七、软件架构设计的误区

  1. 设计架构就是搭框架
  2. 软件架构师不必懂需求
  3. 架构=理想设计
  4. 架构=模块+接口
  5. 只注重功能设计,忽略了约束
  6. 只注重功能设计,没考虑非功能性设计
  7. 忽略了风险
  8. 不计成本的架构设计
    路漫漫其修远兮,吾将上下而求索。在软件架构之路越走越远。