9.6 架构设计
9.2 节讨论了实现软件质量属性的战术,这些战术可以看做设计的基本“构建块”,通过这些构建块,就可以精心设计系统的软件架构了。
架构模式也称为架构风格,它是适当地选取战术的结果,这些固定的结果(模式)在高层抽象层次上具有普遍实用性和复用性。
通过架构模式,架构设计师可以借鉴和复用他人的经验,看看类似的问题别人是如何解决的。但不要把模式看成是一个硬性的解决方法,它只是一种解决问题的思路。Martin Fowler 曾说:“模式和业务构件的区别就在于模式会引发你的思考。”
1.演变交付生命周期
业界已开发出各种软件生命周期模型,其中把架构放在一个适当位置的模型中,典型的有演变交付生命周期模型,如图 9-17 所示。
在生命周期模型中,架构设计就是从初步的需求分析开始逐步进行循环迭代(图 9-17 中的反向箭头说明了这一点)。即:一方面在了解系统需求前,不能开始设计架构;另一方面,刚开始进行设计架构时并不需要等到全部需求都收集到。架构是由“架构驱动”因素“塑造”的,架构因素是指少数关键的、优先级别最高的业务目标质量需求。架构由少数关键需求决定并在循环迭代中处于基本稳定状态,它作为演变的基础设施。
2.属性驱动设计法
上述模型强调先建立软件架构,再把架构作为骨架,在骨架上循环迭代,逐步长出有血有肉的系统之躯。属性驱动设计法(Attribute-Driven Design,ADD)就是一种定义软件架构的方法,该方法将分解过程建立在软件必须满足的质量属性之上。
ADD 的输入为:功能需求(一般表示为用例)、限制条件和质量需求(一组特定于系统的质量场景)。
ADD 的步骤如下。
(1)选择要分解的模块。通常是整个系统,要求上述输入都是可获得的(限制条件、功能需求、质量需求)。从系统开始,然后分解为子系统,进一步将子系统分解为子模块。
(2)根据如下步骤对模块进行求精:从具体的质量场景和功能需求集合中选择架构驱动因素。并不是同等看待所有需求,而是在满足了最重要的需求的条件下,才满足不太重要的需求,即针对架构需求有优先级。
选择满足架构驱动因素的架构模式,根据前面的战术创建(或选择)模式。其目标是建立一个由模块类型组成的总体架构模式。实例化模块并根据用例分配功能,使用多个视图进行表示。定义子模块的接口。验证用例和质量场景,并对其进行求精,使它们成为子模式的限制。
(3)对需要进一步分解的每个模块重复上述步骤。
3.按架构组织开发团队
在架构的模块分解结构的最初几个层次相对稳定之后,就可以把这些模块分配给开发小组,其结果就是工作视图。像软件系统一样,开发小组也应该努力做到松耦合、高内聚。即每个模块都构成自己的小领域(专门知识或专门技术),并与其他模块的接口清晰,这样,不同的模块分到不同的开发小组中,就能减少各开发小组之间的沟通成本,而在各开发小组内部,由于是处理小领域的问题,容易建立起有效的沟通机制,如成员有这个小领域的背景
知识(或培训获得)、共享决策信息。
同时,项目计划在架构确定之后可以结合分工进一步明细化,特别要规划好接口提供的时间点,保证项目开发的整体协调性。
4.开发骨架系统
演变交付生命周期模型中有两个循环,第一个循环是通过迭代的方式开发出软件架构,第二个循环是在架构的基础上通过迭代的方式开发出交付的最终版本。开发骨架系统就是第二个循环的第一步。这一步就是以架构为指导,开发一个可运行的原型(骨架系统)。
在骨架系统开发过程中要注意对接口进行充分协商,避免先开发的部分强制随后部分满足其不合理的接口要求。骨架系统完成后,就可以在其上进行增量开发,直到软件开发完成。
5.利用商用构件进行开发
模式本来就是针对特定问题的解,因此,针对需求的特点,也可以选用相应的模式来设计架构,并利用对应于该模式的商用构件进行软件开发。例如可以使用 J2EE/EJB 进行开发面向对象的分布式系统。
9.7 软件架构文档化
记录软件架构的活动就是架构编档过程,也就是架构的文档化。它包含两个方面:一是过程,编档过程能促使架构设计师进一步思考,使得架构更加完善;二是结果,描述架构的文档将作为架构开发的成果,供项目关系人使用。
1.架构文档的使用者
架构文档的使用者是架构的项目关系人。编写技术文档(尤其是软件架构文档)最基本的原则之一是要从读者的角度来编写,易于编写但很难阅读的文档是不受欢迎的。架构的主要用途是充当项目关系人之间进行交流的工具,文档则促进了这种交流—— 架构项目关系人希望从架构文档中获得自己所关心的架构信息,如:系统实现人员希望文档提供关于开发活动的不能违反的限制及可利用的自由;测试人员和集成人员希望能从文档中得到必须组合在一起的各部分,并以此得到一个正确的测试黑箱;项目经理希望根据所确定的工作任务组建开发小组,规划和分配项目资源。
2.合理的编档规则编写架构文档和编写其他文档一样,必须遵守一些基本规则,这里将任何软件编档(包括软件架构编档)的规则归纳为 7 条:
(1)从读者的角度编写文档。
(2)避免出现不必要的重复。
(3)避免歧义。
(4)使用标准结构。
(5)记录基本原理。
(6)使文档保持更新,但更新频率不要过高。
(7)针对目标的适宜性对文档进行评审。
3.视图编档
视图是最重要的软件架构编档概念,本书将在 9.11 节中专门讨论架构的视图。视图的概念为架构设计师提供了进行软件架构编档的基本原则。架构文档化就是将相关视图编成文档,并补充多个视图的关联关系。视图编档的组织结构(内容及编排次序、大纲)虽然目前还没有工业标准模板,研究者
(Bachmann 等人)提出的文档组织结构包含 7 个部分,如图 9-18 所示。
(1)视图概述:对系统进行概括性的描述,包含视图的主要元素和元素间的关系(但并不包含所有元素和元素间的关系,如:与错误处理相关的内容可以放在支持文档中)。主要表示可用多个形式:图形、表格、文本,通常用图形形式,使用 UML 语言来描述。
(2)元素目录:对主要表示中所描述的元素及其关系进行详细描述,包括:元素及其 属性、关系及其属性、元素接口、元素行为。
这部分是文档的主要组成部分,其中要注意:—对元素及其协同工作的行为进行编档,如用 UML 的顺序图和状态图描述行为;
—对接口进行编档,图 9-19 说明了这部分的内容。
(3)上下文图:用图形展示系统如何与其环境相关。
(4)可变性指南:描述架构的可变化点,如在软件产品线中,产品线架构通过变化,适用于多个系统,因此,文档中应包含这些变化点,如各系统要做出选择的选项、做出选择的时间。
(5)架构背景:为架构的合理性提供足够的、令人信服的论据。包括:基本原理、分析结果及设计中所反映的假定。
(6)术语表:对文档中每个术语进行简要说明。
(7)其他信息:描述不属于架构方面的必要信息,如管理信息(创作者、配置控制数据及变更历史)。
4.跨视图文档
软件架构由多个视图文档来反映,按前面所述的要求完成每个视图的文档后,需要对这些文档进行一个整体的“打包”工作,这就是跨视图文档。它包括如下内容:
(1)文档有哪些内容,它们是如何组织的:视图目录(含哪些视图);视图模板(即前面描述的视图文档,企业可以通过规范化来定义统一的、公共的视图模板)。
(2)架构概述:它描述系统的目的、视图之间的关联、元素表及索引、项目词汇。
(3)为什么架构是这样的(基本原理):跨视图基本原理解释了整体架构实际上是其需求的一个解决方案。即解释了做出决策的原因、方案的限制、改变决策时的影响及意义。
5.使用 UML
UML 已经成为对软件架构进行文档化的事实上的标准表示法。在视图文档的组织结构中,UML 主要用于表示元素或元素组的行为。
有关 UML 的详细内容,请阅读 8.4.3 节。
6.软件架构重构
前面已论述了架构编档,即在架构设计时完成编档工作。但是还有另外一种情况:系统已经存在,但不知其架构,即架构没有通过文档很好地保留下来(文档的缺失/失效)。如何维护这样的系统并管理其演变?其关键就是要找到软件架构,软件架构重构就是研究解决这一问题的方法,它是反向工程之一。
架构重构需要工具的支持,但任何一个工具或工具集对架构重构都是不够的。因为:工具往往是面向特定语言的;数据提取工具经常返回不完整的或错误的结果,因此,应在多个工具提供的结果间进行补充、验证和判断;
重构的目的(文档的用途)不同,决定了需要提取什么数据,这反过来影响了工具的选择。以此为原则,就是架构重构的工作台方法,如 SEI 开发的 Dali。软件架构重构由以下活动组成,这些活动以迭代方式进行,如图 9-20 所示。
(1)信息提取(View Extraction)。可以使用各种工具进行信息提取,如解析器、语法分析器等;可以利用 build 和 makefile 文件中关于模块的依赖关系;可以从源代码、编译时制品和设计制品中提取静态信息;可以使用分析工具提取动态信息。
(2)数据库构造(Database Construction):将提取的信息转化为标准的形式,并置于数据库中。
(3)视图融合(View Fusion):将数据库中的信息组合在一起,生成该架构的一个内聚的视图。
(4)重构(Reconstruction):构建数据抽象和各种表示以生成架构表示,主要由两个活动组成:可视化和交互、模式定义和识别。最后生成需要的架构文档(Documentation)。
上述过程中,架构是由重构人员通过对系统做出一组假定来获得,为了最有效地生成这些假定并对其进行验证,必须让熟悉系统的人参与此项工作,包括过去参与系统开发的人员或现在正在对其进行维护的人员。
9.8 软件架构评估
软件架构评估是在对架构分析、评估的基础上,对架构策略的选取进行决策。它也可以灵活地运用于对软件架构进行评审等工作中。
9.8.1 软件架构评估的方法
业界已开发出多种软件架构评估的方法,按基于的技术手段来看,可以分为三类:基于调查问卷或检查表的方式、基于场景的方式和基于度量的方式。
(1)基于调查问卷或检查表的方式:该方式的关键是要设计好问卷或检查表,它充分利用系统相关人员的经验和知识,获得对架构的评估。其缺点是在很大程度上依赖于评估人员的主观推断。
(2)基于场景的方式:基于场景的方式由 SEI 首先提出并应用在架构权衡分析法(Architecture Tradeoff Analysis Method,ATAM)和软件架构分析方法(Software Architecture Analysis Method,SAAM)中。它是通过分析软件架构对场景(也就是对系统的使用或修改活动)的支持程度,从而判断该架构对这一场景所代表的质量需求的满足程度。下节将对ATAM 进行重点介绍。
(3)基于度量的方式:它是建立在软件架构度量的基础上的,涉及三个基本活动,首先需要建立质量属性和度量之间的映射原则,即确定怎样从度量结果推出系统具有什么样的质量属性;然后从软件架构文档中获取度量信息;最后根据映射原则分析推导出系统的质量属性。它能提供更为客观和量化的质量评估,但它对评估人员及其使用的技术有较高的要求。ATAM 中也使用了度量的思想(度量效用)。
9.8.2 架构的权衡分析法
从技术角度对软件架构进行评估,旨在通过分析来预见软件的质量;通过分析来创建、选择、评估与比较不同的架构。例如,Kazman 等人在 2000 年提出的架构的 ATAM 方法。
ATAM 方法不但能够揭示架构如何满足特定的质量需求(例如,性能和可修改性),而且还提供了分析这些质量需求之间交互作用的方法。使用 ATAM 方法评价一个软件架构的目的是理解架构设计满足系统质量需求的结果。ATAM 产生如下结果。
(1)一个简洁的架构表述:ATAM 的一个要求是在一小时内表述架构,这样就得到了一个简洁、可理解的、面向普通项目关系人的架构表述。它是从架构文档中提炼形成的。
(2)表述清楚的业务目标。
(3)用场景集合捕获质量需求。
(4)架构决策到质量需求的映射。
(5)所确定的敏感点和权衡点集合:这个集合是一些对一个或多个质量属性具有显著影响的架构决策。如:备份数据库就是这样一个架构决策,它对可靠性产生正面影响,而对系统性能产生负面影响,因此需要进行权衡。
(6)有风险决策和无风险决策。
(7)风险主题的集合。找到这些风险主题旨在采取相应的措施。
(8)产生一些附属结果。评估过程形成的文档(经受住了评估的考验)可以作为经验保留下来。
(9)还产生一些无形结果,如能够使项目关系人产生“团队感”,提供了一个交流平台和沟通渠道,使大家更好地理解架构(优势及弱点)。
ATAM 的 9 个步骤如下。
(1)ATAM 方法的表述:评估负责人向参加会议的项目代表介绍 ATAM(简要描述 ATAM 步骤和评估的结果)。
(2)商业动机的表述。项目决策者从商业角度介绍系统的概况。
(3)架构的表述。对架构进行详略适当的介绍。设计师要描述用来满足需求的架构方法或模式,还应描述技术约束条件及与其他系统的交互等。
(4)对架构方法进行分类。通过研究架构文档及倾听上一步的表述,了解系统使用的架构模式和方法(进行明确命名)。
(5)生成质量属性效用树。可以选取这样一棵树:根——质量属性——属性求精(细分)——场景(叶)。修剪这棵树,保留重要场景(不超过 50 个),再对场景按重要性给定优先级(用 H/M/L 的形式),再按场景实现的难易度来确定优先级(用 H/M/L 的形式),这样对所选定的每个场景就有一个优先级对(重要度,难易度),如(H,L)表示该场景重要且易实现。
(6)分析架构方法。评估小组按优先级对上述效用树的场景进行分析(小组成员提问,设计师回答、解释),探查实现场景的架构方法。评估小组把相关架构决策编成文档,确定其有风险决策、无风险决策、敏感点、权衡点,并对其进行分类(分别用表格列出)。
(7)集体讨论并确定场景的优先级。由于项目关系人的不同角色及所关心的场景不一致,因此,应鼓励项目关系人考虑效用树中尚未分析过的场景。集体讨论后,可通过投票的方式获得各场景的优先级。通过把集体讨论确定了优先级的一组场景与效用树中的那组场景进行比较,能发现设计师所想的与项目关系人实际所要的是否存在差距,这一差距是否导致风险。
(8)分析架构方法。类似于第 6 步,这时,评估小组引导设计师实现在第 7 步中得到的优先级最高的场景。
(9)结果的表述。把在 ATAM 分析中得到的各种信息进行归纳总结,并呈现给项目关系人。主要有:
- 已编写了文档的架构方法;
- 经过讨论得到的场景集合及其优先级;
- 效用树;
- 所发现的有风险决策;
- 已编成文档的无风险决策;
- 所发现的敏感点和权衡点。
9.8.3 成本效益分析法
在大型复杂系统中最大的权衡通常必须考虑经济性,因此,需要从经济角度建立成本、收益、风险和进度等方面软件的“经济”模型。成本效益分析法(the Cost Benefit Analysis Method,CBAM)是在 ATAM 上构建,用来对架构设计决策的成本和收益进行建模,是优化此类决策的一种手段。CBAM 的思想就是架构策略影响系统的质量属性,反过来这些质量属性又会为系统的项目关系人带来一些收益(称为“效用”),CBAM 协助项目关系人根据其
投资回报(ROI)选择架构策略。CBAM 在 ATAM 结束时开始,它实际上用了 ATAM 评估的结果。
CBAM 的步骤如下。
(1)整理场景。整理 ATAM 中获取的场景,根据商业目标确定这些场景的优先级,并选取优先级最高的 1/3 的场景进行分析。
(2)对场景进行求精。为每个场景获取最坏情况、当前情况、期望情况和最好情况的质量属性响应级别。
(3)确定场景的优先级。项目关系人对场景进行投票,其投票是基于每个场景“所期望的”响应值,根据投票结果和票的权值,生成一个分值(场景的权值)。
(4)分配效用。对场景的响应级别(最坏情况、当前情况、期望情况和最好情况)确定效用表。
(5)架构策略涉及哪些质量属性及响应级别,形成相关的策略—场景—响应级别的对应关系。
(6)使用内插法确定“期望的”质量属性响应级别的效用。即根据第 4 步的效用表以及第 5 步的对应关系,确定架构策略及其对应场景的效用表。
(7)计算各架构策略的总收益。根据第 3 步的场景的权值及第 6 步的架构策略效用表,计算出架构策略的总收益得分。
(8)根据受成本限制影响的 ROI(Return On Investment,投资报酬率)选择架构策略。根据开发经验估算架构策略的成本,结合第 7 步的收益,计算出架构策略的 ROI,按 ROI 排序,从而确定选取策略的优先级。