软考|系分|第十二章|软件架构设计(下) 软件架构作为一个概念起源于1968年Edsger Dijkstra 和20世纪70年代初 David Parnas的 研究,直到1990年,软件架构一词才得到广泛使用。计算机科学领域自形成就遇到了与复杂性 相关的问题。早期开发人员通过选择正确的数据结构、开发算法和应用关注点的分离来解决复 杂问题。伴随着软件密集型系统的出现,学者开始重视软件架构标准的设计。IEEE 1471-2000 是软件架构领域的第一个针对“软件密集型系统架构描述的推荐实现”的正式标准,侧重于软 件密集型系统和更通用的软件系统,例如信息系统、嵌入式系统等,在软件开发、操作和演进 中起着重要作用。为了达到软件架构标准,降低软件复杂度,以得到论域中较为简单的概念, IEEE 1471-2000定义了以下软件架构标准要素之间的关系,具体分为5个层次:(1)任务( Mission) 。任务是指一种使用或操作,是一个系统想要满足一名或多名利益相 关者的目标,为达成这个目标,完成相对应的软件架构设计。这是软件架构标准设计的第一步, 即需要明确软件的任务是什么,从而根据任务来进行软件架构的设计。任务通常可以是为了更 大的利益、为了更高的市场占有率或完善产品系列等,这是软件架构标准中的第一层设计标准。(2)环境 ( Environment)、系统 ( System) 以及架构( Architecture)。一个完整的系统是由 一系列组件组成的,将这些组件组织在一起,相互作用从而完成一个或者一些特殊的功能。在 软件开发过程中,系统是任何对其设计、构造、部署和演变有重要影响的组成,包括单个应用 程序、传统意义上的系统、子系统、产品线、产品系列、整个企业和其他利益。同时系统不可 能单独存在,它总是存在于一个环境之中。在软件架构标准中,将系统范围之外的、对系统有 影响、有交互的客观存在定义为环境,有时也称为上下文。并且每一个系统都应该实现一种或 多种的软件架构,无论是否有意设计或者自发形成,这是软件架构标准中为了完成任务所进行 的第二层设计标准。(3)利益相关者( Stackholder)、架构说明( Architecture Description) 以及原理 ( Rationale)。一个系统拥有多个利益相关者,并且系统架构也需要架构说明来进行描述,从而满足不同利益 相关者的利益,从架构描述中可以识别出不同利益相关者的相关利益。同时在设计软件架构时, 软件架构工程师需要做出许多取舍以及选择,需要给出选择或者不选择的理由,以及架构设计 是如何满足功能性需求和非功能性需求的,这是软件架构标准第三层的设计标准。(4)关注( Concern) 、 关注点( Viewpoint) 、视图(View) 。 一个系统的利益相关者对系统 和与其有关的问题进行关注。一个关注点可能由一个或多个利益相关者持有。在整个生命周期 中,对系统的需求和要求以及实施和运行的考虑等都可能成为关注点。关注点可以通过多种形 式表现出来,例如与一个或多个利益相关者的需求、目标、期望、责任、要求、设计约束、假 设、依赖性、质量属性、架构决策、风险或其他与系统有关的问题有关。不同的利益相关者其关注点不尽相同,有时甚至是矛盾的。站在不同的关注点,就会对系统架构形成不同的视图, 视图和关注点是一一对应的关系。并且视图受关注点的制约:关注点确立了构建、解释和分析 视图的规范。关注点的制约可以包括语言、符号、模型种类、设计规则,以及建模方法、分析 技术和其他对视图的操作。(5)关注点库(Library Viewpoint)、模型( Model) 。关注点库中存放了前人针对各种系 统、各种不同的利益相关者、各种不同的关注点总结出来的观察点,方便后人参考使用。Model, 可直译为模型,它是用来表示视图的方法,即使用图形化的表示,将不同视图下的 系统元素组织起来,并将这些元素整体发挥的作用表现出来。IEEE 1471-2000作为第一个软件架构设计的标准,侧重于软件架构标准的描述,而不是软 件架构的组建过程。首先,IEEE 1471-2000定义了软件架构元素的内容。其次,它指出软件架 构必须存在一个或多个视图,这些视图必须能反映利益相关者的关注点。最后,必须根据每个 被认定为关键架构的原理,来演示软件架构工程师考虑的权衡,展示对于软件架构设计的取舍。 通过对关键概念和术语的定义,该标准为软件架构的实践提供了基础,并作为未来架构发展的 基础。其各个要素的关系如图12-19所示。图12-19 IEEE 1471-2000软件架构元素及要素间的关系 2006年,ISO 采纳了IEEE 1471-2000作为内部标准,然后IEEE 与ISO 一起修订,并经 过多次修改,最终发布ISO/IEC/IEEE 42010:2022-Software,Systems and Enterprise Architecture Description,该标准是目前公认的软件架构标准。传统的软件开发过程从概念到实现可以划 分为若干个阶段,包括问题定义、需求分析、 软件设计、软件实现及软件测试等。如果采用 传统的软件开发模型,软件体系结构的建立应 位于需求分析之后、概要设计之前。能很好地支持软件重用等缺点。基于架构的软. 件开发模型( ABSDM) 把整个基于体系结构的软件过程划分为体系结构需求、设计、文档化、 复审、实现和演化等6个子过程,如图12-20 所示。需求是指用户对目标软件系统在功能、行 为、性能、设计约束等方面的期望。体系结构 需求受技术环境和体系结构设计师的经验影响。 需求过程主要是获取用户需求,标识系统中所 要用到的构件。体系结构需求过程如图12-21 所示。如果以前有类似的系统体系结构的需求, 我们可以从需求库中取出,加以利用和修改, 以节省需求获取的时间,减少重复劳动,提高 开发效率。体系结构需求一般来自三个方面,分别是 系统的质量目标、系统的商业目标和系统开发 人员的商业目标。软件体系结构需求获取过程 主要是定义开发人员必须实现的软件功能,使 得用户能完成他们的任务,从而满足业务上的 功能需求。与此同时,还要获得软件质量属性, 满足一些非功能需求。在图12-21中虚线框部分属于标识构件过程,此过程为系统生成初始逻辑结构,包含大致 的构件。这一过程又可分为三步来实现。第一步:生成类图。生成类图的CASE工具有很多,例如Rational Rose 2000能自动生成第二步:对类进行分组。在生成的类图基础上,使用一些标准对类进行分组可以大大简化 类图结构,使之更清晰。一般地,与其他类隔离的类形成一个组,由概括关联的类组成一个附 加组,由聚合或合成关联的类也形成一个附加组。第三步:把类打包成构件。把在第二步得到的类簇打包成构件,这些构件可以分组合并成 更大的构件。组织一个由不同代表(如分析人员、客户、设计人员、测试人员)组成的小组,对体系结 构需求及相关构件进行仔细的审查。审查的主要内容包括所获取的需求是否真实反映了用户的 要求,类的分组是否合理,构件合并是否合理等。必要时,可以在“需求获取一标识构件一需 求评审”之间进行迭代。 体系结构需求用来激发和调整设计决策,不同的视图被 用来表达与质量目标有关的信息。体系结构设计是一个迭代 过程,如果要开发的系统能够从已有的系统中导出大部分, 则可以使用已有系统的设计过程。软件体系结构设计过程如 图12-22所示。在建立体系结构的初期,选择一个合适的体系结构风 格是首要的。在这个风格基础上,开发人员通过体系结构模 型,可以获得关于体系结构属性的理解。此时,虽然这个模 型是理想化的(其中的某些部分可能错误地表示了应用的特 征),但是,该模型为将来的实现和演化过程建立了目标。把在体系结构需求阶段已标识的构件映射到体系结构中,将产生一个中间结构,这个中间 结构只包含那些能明确适合体系结构模型的构件。 为了把所有已标识的构件集成到体系结构中,必须认真分析这些构件的相互作用和关系。一旦决定了关键的构件之间的关系和相互作用,就可以在第2阶段得到的中间结构的基础 上进行精化。一旦设计了软件体系结构,必须邀请独立于系统开发的外部人员对体系结构进行评审。绝大多数的体系结构都是抽象的,由一些概念上的构件组成。例如,层的概念在任何程序 设计语言中都不存在。因此,要让系统分析员和程序员去实现体系结构,还必须要把体系结构 进行文档化。在系统演化的每一个阶段,文档都是系统设计与开发人员的通信媒介,是为验证 体系结构设计和提炼或修改这些设计(必要时)所执行预先分析的基础。体系结构文档化过程的主要输出结果是体系结构规格说明和测试体系结构需求的质量设计 说明书这两个文档。这些文档是需求模型构件的精确的形式化的描述,作为用户和开发者之间 的一个协约。软件体系结构文档的要求与软件开发项目中的其他文档是类似的。文档的完整性 和质量是软件体系结构成功的关键因素。文档要从使用者的角度进行编写,必须分发给所有与 系统有关的开发人员,且必须保证开发者手上的文档是最新的。从图12-20中可以看出,体系结构设计、体系结构文档化和体系结构复审是一个迭代过程。 从这个角度来说,在分析一个主版本的软件体系结构之后,要安排一次由外部人员(用户代表 和领域专家)参加的复审。鉴于体系结构文档标准化,以及风险识别的现实情况,通常我们根据架构设计,搭建一个可 运行的最小化系统用于评估和测试体系架构是否满足需要,是否存在可识别的技术和协作风险。复审的目的是标识潜在的风险,及早发现体系结构设计中的缺陷和错误,包括体系结构能 否满足需求、质量需求是否在设计中得到体现、层次是否清晰、构件的划分是否合理、文档表 达是否明确、构件的设计是否满足功能与性能的要求等。所谓“实现”就是要用实体来显示出一个软件体系结 构,即要符合体系结构所描述的结构性设计决策,分割成 规定的构件,按规定方式互相交互。体系结构的实现过程 如图12-23所示。图12-23中的虚线框部分是体系结构的实现过程。整 个实现过程是以复审后的文档化的体系结构说明书为基础 的,每个构件必须满足软件体系结构中说明的对其他构件 的责任。这些决定即实现的约束是在系统级或项目范围内 给出的,每个构件上工作的实现者是看不见的。在体系结构说明书中,已经定义了系统中的构件与构 件之间的关系。因为在体系结构层次上,构件接口约束对 外唯一地代表了构件,所以可以从构件库中查找符合接口 约束的构件,必要时开发新的满足要求的构件。然后,按 照设计提供的结构,通过组装支持工具把这些构件的实现最后一步是测试,包括单个构件的功能性测试和被组装应用的整体功能和性能测试。在构件开发过程中,用户的需求可能还有变 动。在软件开发完毕,正常运行后,由一个单位 移植到另一个单位,需求也会发生变化。在这两 种情况下,就必须相应地修改软件体系结构,以 适应新的变化了的软件需求。体系结构演化过程 如图12-24所示。体系结构演化是使用系统演化步骤去修改应 用,以满足新的需求。主要包括以下6个步骤。首先必须对用户需求的变化进行归类,使变 化的需求与已有构件对应。对找不到对应构件的 变动,要特别做好标记,在后续工作中,将创建 新的构件,以对应这部分变化的需求。在改变原有结构之前,开发组织必须制订一个周密的体系结构演化计划,作为后续演化开 发工作的指南。在演化计划的基础上,开发人员可根据在第1步得到的需求变动的归类情况,决定是否修 改或删除存在的构件、增加新构件。最后,对修改和增加的构件进行功能性测试。随着构件的增加、删除和修改,构件之间的控制流必须得到更新。通过组装支持工具把这些构件的实现体组装起来,完成整个软件系统的连接与合成,形成 新的体系结构。然后对组装后的系统整体功能和性能进行测试。对以上步骤进行确认,进行技术评审。评审组装后的体系结构是否反映需求变动,符合用 户需求。如果不符合,则需要在第2~6步之间进行迭代。在原来系统上所作的所有修改必须集成到原来的体系结构中,完成一次演化过程。 软件系统属性包括功能属性和质量属性,软件架构重点关注的是质量属性。架构的基本需 求是在满足功能属性的前提下,关注软件系统质量属性。为了精确、定量地表达系统的质量属 性,通常会采用质量属性场景的方式进行描述。在确定软件系统架构,精确描述质量属性场景后,就需要对系统架构进行评估。软件架构 评估是在对架构分析、评估的基础上,对架构策略的选取进行决策。它也可以灵活地运用于软 件架构评审等工作。 软件系统的质量就是“软件系统与明确地和隐含地定义的需求相一致的程度”。更具体地 说,软件系统质量是软件与明确叙述的功能和性能需求文档中明确描述的开发标准以及任何专 业开发的软件产品都应该具有的隐含特征相一致的程度。根据GB/T 25000.10—2016的定义, 从管理角度对软件系统质量进行度量,可将影响软件质量的主要因素划分为6种维度特性:功 能性、可靠性、易用性、效率、维护性与可移植性。其中,功能性包括适合性、准确性、互操 作性、依从性和安全性;可靠性包括容错性、易恢复性和成熟性;易用性包括易学性、易理解 性和易操作性;效率包括资源特性和时间特性;维护性包括可测试性、可修改性、稳定性和易 分析性;可移植性包括适应性、易安装性、一致性和可替换性。软件系统质量属性( Quality Attribute) 是一个系统的可测量或者可测试的属性,用来描述 系统满足利益相关者( Stakeholders) 需求的程度。基于软件系统的生命周期,可以将软件系统 的质量属性分为开发期质量属性和运行期质量属性两部分。开发期质量属性主要指在软件开发阶段所关注的质量属性,主要包含以下6个方面:(2)可扩展性:指软件因适应新需求或需求变化而增加新功能的能力,也称为灵活性。(3)可重用性:指重用软件系统或某一部分的难易程度。(4)可测试性:指对软件测试以证明其满足需求规范的难易程度。(5)可维护性:当需要修改缺陷、增加功能、提高质量属性时,识别修改点并实施修改的 难易程度。(6)可移植性:将软件系统从一个运行环境转移到另一个不同的运行环境的难易程度。运行期质量属性主要指在软件运行阶段所关注的质量属性,主要包含以下7个方面:(1) 性能:指软件系统及时提供相应服务的能力,如速度、吞吐量和容量等的要求。(2)安全性:指软件系统同时兼顾向合法用户提供服务,以及阻止非授权使用的能力。(3)可伸缩性:指当用户数和数据量增加时,软件系统维持高服务质量的能力。例如,通 过增加服务器来提高能力。(4)互操作性:指本软件系统与其他系统交换数据和相互调用服务的难易程度。(5)可靠性:指软件系统在一定的时间内持续无故障运行的能力。(6)可用性:指系统在一定时间内正常工作的时间所占的比例。可用性会受到系统错误、 恶意攻击和高负载等问题的影响。(7) 健壮性:指软件系统在非正常情况(如用户进行了非法操作、相关的软硬件系统发生 了故障等)下仍能够正常运行的能力,也称为鲁棒性或容错性。 为了评价一个软件系统,特别是软件系统的架构,需要进行架构评估。在架构评估过程中, 评估人员所关注的是系统的质量属性。评估方法所普遍关注的质量属性有以下几种。性能 ( Performance) 是指系统的响应能力,即要经过多长时间才能对某个事件做出响应, 或者在某段时间内系统所能处理的事件的个数。经常用单位时间内所处理事务的数量或系统完 成某个事务处理所需的时间来对性能进行定量的表示。性能测试经常要使用基准测试程序。可靠性( Reliability) 是软件系统在应用或系统错误面前,在意外或错误使用的情况下维持 软件系统的功能特性的基本能力。可靠性是最重要的软件特性,通常用来衡量在规定的条件和 时间内,软件完成规定功能的能力。可靠性通常用平均无故障时间 ( MTTF) 和平均故障间隔时间( MTBF) 来衡量。在失效率为常数和修复时间很短的情况下,MTTF 和MTBF 几乎相等。(1)容错。其目的是在错误发生时确保系统正确的行为,并进行内部“修复”。例如,在一 个分布式软件系统中失去了一个与远程构件的连接,接下来恢复了连接。在修复这样的错误之 后,软件系统可以重新或重复执行进程间的操作直到错误再次发生。(2)健壮性。这里说的健壮性是保护应用程序不受错误使用和错误输入的影响,在发生意 外错误事件时确保应用系统处于预先定义好的状态。值得注意的是,和容错相比,健壮性并不 是指在错误发生时软件可以继续运行,它只能保证软件按照某种已经定义好的方式终止执行。 软件架构对软件系统的可靠性有巨大的影响。例如,软件架构设计上通过在应用程序内部采用 冗余机制,或集成监控构件和异常处理,以提升系统可靠性。可用性( Availability) 是系统能够正常运行的时间比例,经常用两次故障之间的时间长度 或在出现故障时系统能够恢复正常的速度来表示。安全性( Security) 是指系统在向合法用户提供服务的同时能够阻止非授权用户使用的企图 或拒绝服务的能力。安全性可根据系统可能受到的安全威胁类型来分类。安全性又可划分为机 密性、完整性、不可否认性及可控性等特性。其中,机密性保证信息不泄露给未授权的用户、实体或过程;完整性保证信息的完整和准确,防止信息被非法修改;不可否认性是指信息交换 的双方不能否认其在交换过程中发送信息或接收信息的行为;可控性保证对信息的传播及内容 具有控制的能力,防止为非法者所用。可修改性 ( Modifiability) 是指能够快速地以较高的性价比对系统进行变更的能力。通常 以某些具体的变更为基准,通过考察这些变更的代价衡量可修改性。可修改性包含以下4个 方面。(1)可维护性 ( Maintainability)。这主要体现在问题的修复上:在错误发生后“修复”软 件系统。可维护性好的软件架构往往能做局部性的修改,并能使这种修改对其他构件的负面影 响最小化。(2)可扩展性( Extendibility)。这一点关注的是使用新特性来扩展软件系统,以及使用改 进版本方式替换构件并删除不需要或不必要的特性和构件。为了实现可扩展性,软件系统需要 松散耦合的构件。其目标是实现一种架构,能使开发人员在不影响构件客户的情况下替换构件。 支持把新构件集成到现有的架构中也是必要的。(3)结构重组( Reassemble)。这一点处理的是重新组织软件系统的构件及构件间的关系, 例如通过将构件移动到一个不同的子系统来改变它的位置。为了支持结构重组,软件系统需要 精心设计构件之间的关系。理想情况下,它们允许开发人员在不影响实现的主体部分的情况下 灵活地配置构件。(4)可移植性 ( Portability) 。 可移植性使软件系统适用于多种硬件平台、用户界面、操 作系统、编程语言或编译器。为了实现可移植,需要按照硬件、软件无关的方式组织软件系 统。可移植性是系统能够在不同计算环境下运行的能力,这些环境可能是硬件、软件,也可 能是两者的结合。如果移植到新的系统需要做适当更改,则该可移植性就是一种特殊的可修 改性。功能性( Functionality) 是系统完成所期望工作的能力。一项任务的完成需要系统中许多或 大多数构件的相互协作。可变性 ( Changeability) 是指架构经扩充或变更而成为新架构的能力。这种新架构应该符 合预先定义的规则,在某些具体方面不同于原有的架构。当要将某个架构作为一系列相关产品 (例如,软件产品线)的基础时,可变性是很重要的。作为系统组成部分的软件不是独立存在的,通常与其他系统或自身环境相互作用。为了支 持互操作性,软件架构必须为外部可视的功能特性和数据结构提供精心设计的软件入口。程序 和用其他编程语言编写的软件系统的交互作用就是互操作性的问题,这种互操作性也影响应用 的软件架构。为了精确描述软件系统的质量属性,通常采用质量属性场景( Quality Attribute Scenario) 作 为描述质量属性的手段。质量属性场景是一个具体的质量属性需求,是利益相关者与系统的交 互的简短陈述。质量属性场景是一种面向特定质量属性的需求。它由6部分组成:刺激源(Source): 指某个生成该刺激的实体(人、计算机系统或者任何其他刺激器)。刺激( Stimulus): 该刺激是当刺激到达系统时需要考虑的条件。环境 ( Environment): 该刺激在某些条件下发生。当激励/刺激产生时,系统可能处于过载 或者运行状态,也可能是其他情况。制品 ( Artifact): 某个制品被激励。这可能是整个系统,也可能是系统的一部分。响应 ( Response): 该响应是在激励到达后所采取的行动。响应度量( Measurement): 当响应发生时,应当能以某种方式对其进行度量,以对需求进 行测试。质量属性场景主要关注可用性、可修改性、性能、可测试性、易用性和安全性等6类质量 属性,下面分别列表进行介绍。可用性质量属性场景所关注的方面包括系统故障发生的频率、出现故障时会发生什么情况、 允许系统有多长时间正常运行、什么时候可以安全地出现故障、如何防止故障的发生以及发生 故障时要求进行哪种通知。表12-1给出了详细描述。●在一段预先指定的时间间隔内不可用,时间间隔取决于系统的关键程度在正常或降 级模式下运行系统必须可用的时间间隔、可用时间、系统可以在降级模式下运行的时间间隔、故障修 复时间可修改性质量属性场景主要关注系统在改变功能、质量属性时需要付出的成本和难度,可修改性质量属性场景可能发生在系统设计、编译、构建、运行等多种情况和环境下,表12-2给 出了详细描述。查找架构中需要修改的位置,进行修改且不会影响其他功能,对所做的修改进行测试, 部署所做的修改根据所影响元素的数量和修改需求难度等,度量修改该元素的人力成本、修改所需的时 间、修改的资金成本性能质量属性场景主要关注系统的响应速度,可以通过效率、响应时间、吞吐量、负载来 客观评价性能的好坏,表12-3给出了详细描述。可测试性质量属性场景主要关注系统测试过程中的效率,发现系统缺陷或故障的难易程度 等,表12-4给出了详细描述。开发人员、增量开发人员、系统验证人员、客户验收测试人员、系统用户已完成的分析、架构、设计、类和子系统集成;所交付的系统已执行的可执行语句的百分比、如果存在缺陷出现故障的概率、执行测试的时间、测试 中最长依赖的长度、准备测试环境的时间易用性质量属性场景主要关注用户在使用系统时的容易程度,包括系统的学习曲线、完成 操作的效率、对系统使用过程的满意程度等,表12-5给出了详细描述。想要学习系统特性、有效使用系统、使错误的影响最低、适配系统、对系统满意(1)系统提供以下一个或多个响应来支持“学习系统特性”:帮助系统与环境联系紧密;界面为用户所熟悉;在不熟悉的环境中,界面是可以使用的(2)系统提供以下一个或多个响应来支持“有效使用系统”:数据和(或)命令的聚合;已输入的数据和(或)命令的重用;支持在界面中的有效导航; 具有一致操作的不同视图;全面搜索;多个同时进行的活动(3)系统提供以下一个或多个响应来“使错误的影响最低”:撤销;取消;从系统故障中恢复;识别并纠正用户错误;检索忘记的密码;验证系统资源(4)系统提供以下一个或多个响应来“适配系统”: 定制能力;国际化(5)系统提供以下一个或多个响应来使客户“对系统满意”: 显示系统状态;与客户的节奏合拍任务时间、错误数量、解决问题的 数 量 、用户满意度、用户知识的获得、成功操作在总操 作中所占的比例、损失的时间/丢失的数据量安全性质量属性场景主要关注系统在安全性方面的要素,衡量系统在向合法用户提供服务 的同时,阻止非授权用户使用的能力,表12-6给出了详细描述。正确识别、非正确识别或身份未知的个人或系统(来自内部或外部);经过了授权/未授 权访问了有限的资源或大量资源试图显示数据、改变/删除数据、访问系统服务、降低系统服务的可用性在线或离线、联网或断网、连接有防火墙或者直接连到了网络对用户身份进行认证;隐藏用户的身份;阻止对数据或服务的访问;允许访问数据或服务; 授予或收回对访问数据或服务的许可;根据身份记录访问/修改或试图访问/修改数据/服务;以一种不可读的格式存储数据;识别无法解释的对服务的高需求;通知用户或另外 一个系统,并限制服务的可用性用成功的概率表示,避开安全防范措施所需要的时间/努力/资源;检测到攻击的可能性; 确定攻击或访问/修改数据或服务的个人的可能性;在拒绝服务攻击的情况下仍然获得服 务的百分比;恢复数据/服务;被破坏的数据/服务和/或被拒绝的合法访问的范围