软件架构设计:实用方法及实践
上QQ阅读APP看书,第一时间看更新

2.2 软件架构中的设计

软件系统的架构设计与一般的设计没有什么不同:它涉及做出决策,使用可用的技能和材料以满足需求和约束。在软件架构设计中,我们做出决策来把设计的目的、需求、约束和架构方面关心的问题(我们称之为架构驱动因子),转化为结构,如图2.1所示。然后我们用这些结构来指导项目。它们指导分析和构建,并为培训一个新的项目成员打好基础。它们还指导成本和进度的评估、团队的形成、分析和降低风险,当然,还有实现。

图2.1 架构设计活动概述(架构师图像© Brett Lamb | Dreamstime.com

因此,软件架构设计是一个实现产品和项目目标的关键步骤。有些目标是技术性的(例如,视频游戏或一个电子商务网站实现较低并且可预见的延迟),有些是非技术性的(例如,保持雇佣劳动力,进入一个新的市场,在最终期限前完成)。作为一个软件架构师,你的决定将影响这些目标的实现,并且在某些情况下可能造成矛盾。一个特定的参考架构(例如,富客户端应用程序)的选择可能会为实现你的延迟目标以及为留住你的员工提供一个良好的基础,因为他们已经熟悉了这个参考架构及其配套的技术堆栈。但这种选择可能不会帮助你进入一个新的市场,如手机游戏市场。

在做设计时,一般情况下为了实现一个质量属性而在某些结构上所做的变化将对其他的质量属性产生负面影响。这些取舍是每一个领域里每一个执业架构师无法改变的事实。我们将在本书的例子和案例研究中一遍又一遍地看到它。因此,软件架构师的工作不是找到一个最佳的解决方案,而是找到一个令人满意的方案——通过搜索一个也许很大的设计方案和决策的空间来找到一个可以接受的解决方案。

2.2.1 架构设计

Grady Booch曾经说过,“所有架构都是设计,但并非所有设计都是架构。”那么是什么让一个决策成为“架构”的呢?如果一个决策有非局部的影响并且会影响架构驱动因子的达成,我们就说它是架构的。因此,没有一个决策本质上就是架构的或者非架构的。一个单个要素的缓冲策略的选择可能对系统的其他部分没有什么影响,在这种情况下它是一个实现细节,除了该元素的实现者和维护者外没有人会关注它。另一方面,缓冲策略可能对性能(如果缓冲影响延迟或吞吐量或抖动的目标的实现)、可用性(缓冲区可能不够导致信息丢失)或可修改性(如果我们想在不同的部署或环境中灵活地改变缓冲策略)产生巨大的影响。缓冲策略的选择,与许多设计的选择一样,既不是天生就是架构的也不是非架构的。这个差别完全依赖于当前和预期的架构驱动因子。

2.2.2 元素交互设计

软件架构设计通常只识别一个元素的子集,该子集是系统结构的一部分。这是可以预料的,因为在最初的架构设计中架构师将专注于系统的主要功能。一个用例如何成为主要的用例?业务的重要性、风险和复杂性的考虑组合被加入到这个设计中。当然,对你的用户来说,一切都是当务之急和重中之重。更现实地说,少量的用例提供了最基本的业务价值或体现了最大的风险(如果它们被错误使用),所以这些都被认为是主要的用例。

除了主要的用例以外,每一个系统都有更多需要得到满足的用例。那些支持这些非主要用例的元素和它们的接口被定义为我们所描述的元素交互设计的一部分。这个层次的设计通常在架构设计之后。但是这些元素的位置和关系被我们在软件架构设计过程中做出的决定所限制。这些元素可以是分配给一个人或一个团队的工作单元(也就是模块),所以这个层次的设计不仅对于如何分配非主要的功能很重要,而且对于计划目标(例如,团队的形成与沟通、预算、外包、发布计划、单元和集成测试计划)而言也很重要。

根据系统的规模和复杂性,软件架构师应当参与元素的交互设计,无论是直接参与还是作为审计的角色参与。这种参与确保了系统的重要质量属性没有妥协——例如,元素没有正确地被定义、定位或者连接。这也将有助于软件架构师发现泛化的机会。

2.2.3 元素内部设计

元素交互设计之后的第三层设计,我们称之为元素内部设计。这个层次的设计通常是作为元素开发活动的一部分,在之前设计层次中发现的元素内部结构就在这个层次创建,以满足元素的接口。

在这三个设计层次中,软件架构的决策可以并且一定会发生。此外,在软件架构设计中软件架构师需要像元素内部设计一样尽可能深地挖掘来完成一个特定的软件架构驱动因子。例子之一就是先前讨论的缓冲策略的选择。在这个意义上,软件架构设计涉及大量的细节,这也解释了为什么我们不想在“高层次设计”或“详细设计”这类术语中提及它(参看下面的引文“详细设计?”)。

软件架构设计先于元素交互设计,元素交互设计先于元素内部设计。这在逻辑上是必要的:在元素本身被定义之前我们不能设计元素的内部结构,在一些元素和它们之间的互动模式被定义之前,我们不能推理它们之间的交互。但随着项目的增长和发展,事实上这些活动之间也出现了大量的迭代。

详细设计?

“详细设计”这个术语经常被用来指代模块内部的设计。虽然它被广泛使用,但是我们真的不喜欢这个在某种程度上与“高层次设计”相对的术语。我们喜欢用更精确的术语:“软件架构设计”“元素交互设计”和“元素内部设计”。

毕竟如果你的系统复杂,它的架构设计也可能是相当详细的。一些设计的“细节”也将变得有架构的含义。出于同样的原因,我们也不喜欢“高层次设计”和“低层次设计”这样的术语。谁能真正知道这些术语究竟意味着什么?显然,“高层次设计”应该以某种方式更“高”或更抽象,比“低层次设计”覆盖更多架构性的内容。但除此之外,我们无法为这些术语赋予任何确切的含义。

因此,我们这样建议:避免使用如“高”“低”或“详细”这类术语。总是有一个更好的、更精确的选择,如“架构”“元素交互”或“元素内部”的设计。

仔细考虑你所做决定的影响,你试图在设计文档中传达的信息,以及这些信息可能的读者,然后给这个过程取一个适当的、有意义的名称。