考点:
- 软件架构的概念 ⭐️⭐️⭐️
- 基于架构的软件开发 ⭐️⭐️⭐️⭐️
- 软件架构风格 ⭐️⭐️⭐️⭐️⭐️
- 特定领域软件架构 ⭐️⭐️⭐️
- 软件质量属性 ⭐️⭐️⭐️⭐️⭐️
- 软件架构评估 ⭐️⭐️⭐️⭐️
- 软件产品线 ⭐️⭐️⭐️
- 构件与中间件技术 ⭐️⭐️⭐️
重中之重!!!!!!
目录
1 软件架构概述 ⭐️⭐️⭐️
软件架构/体系结构(Architecture)就是需求分配,即将满足需求的职责分配到组件上。架构设计的目标是确定应用软件的哪些部分将分配到何种硬件。识别出正在开发系统的主要软件构件并分配到系统将要运行的硬件构件。
架构的本质:
- 软件架构为软件系统提供了一个结构、行为和属性的高级抽象。
- 软件架构风格是特定应用领域的惯用模式,架构定义一个词汇表和一组约束。
架构的作用:
- 软件架构是项目干系人进行交流的手段。
- 软件架构是可传递和可复用的模型,通过研究软件架构可能预测软件的质量。
- 软件架构使推理和控制的更改更加简单,有助于循序渐进的原型设计,可以作为培训的基础。
架构从全局考虑,独立于实际问题,更偏向非功能性需求
1.1 ANSI/IEEE 1471-2000标准
ANSI/EEE 1471-2000是描述软件架构的第一个标准,其中要素的关系如下:
- 第一层:mission
- Mission:任务、使命。即为什么要做这个系统,可能的原因有为了更大的赢利、市场占有率更高、完善产品系列等。
- 第二层:Environment、System、Architecture
- System:系统。具体定义为一系列组件组织在一起,相互作用,从而完成一个或者一些特殊的功能。
- Architecture:系统架构。每个系统有一个架构,是对所有利益相关人的关注点(Concern)的响应和回答,通过架构描述(Architecture Description)来说明。
- 第三层:Stakeholder、Architectural Description、Rationale
- 第四层:Concern、Viewpoint、View
- 第五层:Library Viewpoint、Model
- Model:模型。用来表达视图的方法,即描述系统中各种元素如何组织在一起发挥作用,用图形化的表示把看到的东西表达出来。
ANSI/IEEE 1471-2000是对软件密集型系统的架构进行描述的标准。在该标准中,视图(View)这一概念主要用于描述软件架构模型。在此基础上,通常采用视角(Viewpoint)描述某个利益相关人(Stakeholder)所关注架构模型的某一方面。架构(Architecture)则是对所有利益相关人关注点的响应和回答。
软件架构设计是降低成本、改进质量、按时和按需交付产品的关键因素。架构设计能够满足系统的性能、可维护性等品质;能够使得不同的利益相关人达成一致的目标;能够支持项目计划和项目管理等活动;能够有效地管理复杂性;等等。然而系统架构的给出必须建立在需求明确的基础上。
在ANSMIEEE 1471-2000标准中,系统是为了达成利益相关人(Stakeholder)的某些使命(Mission),在特定环境 (Enviroment)中构建的。每一个系统都有一个架构(Architecture)。架构(Architecture)是对所有利益相关人的关注点(Concern)的响应和回答,通过架构描述 (Architecture Description)来说明。每一个利益相关人都有各自的关注点。这些关注点是指对其重要的,与系统的开发、运营或其他方面相关的利益。架构描述(Architecture Description)本质上是多视图的。每一个视图 (View)是从一个特定的视角(Viewpoint)来表述架构的某一个独立的方面。试图用一个单一的视图来覆盖所有的关注点当然是最好的,但实际上这种表述方式将很难理解。视角 (Viewpoint)的选择,基于要解决哪些利益相关人的哪些关注点。它决定了用来创建视图的语言、符号和模型等,以及任何与创建视图相关的建模方法或者分析技术。一个视图(View)包括一个或者多个架构模型(Model),一个模型也可能参与多个视图。模型较文本的表述的好处在于,可以更容易的可视化、检查、分析、管理和集成。
1.2 软件架构RUP“4+1”视图
架构发展历程图:
视角与视图:从不同的视角来检查,会有不同的视图。
架构的统一过程模型(RUP)“4+1”视图与OOA中的UML的“4+1”视图相互对应,相互匹配使用(因为架构紧接于需求分析之后)。如下所示:
- 左上——逻辑视图(Logical View):主要支持系统的功能需求,即系统提供给最终用户的服务。在逻辑视图中,系统分解成一系列的功能抽象,这些抽象主要来自问题领域。这种分解不但可以用来进行功能分析,而且可用作标识在整个系统的各个不同部分的通用机制和设计元素。在OO技术中,通过抽象、封装和继承,可以用对象模型来代表逻辑视图,用类图来描述逻辑视图。逻辑视图中使用的风格为面向对象的风格,在设计中要注意保持一个单一的、内聚的对象模型贯穿整个系统。——功能需求(同UML)
- 右上——开发视图(Development View)/模块视图:主要侧重于开发人员对软件模块的组织和管理。开发视图要考虑软件内部的需求,例如,软件开发的容易性、软件的复用性和软件的通用性,要充分考虑由于具体开发工具的不同而带来的局限性。开发视图通过系统I/O关系的模型图和子系统图来描述。——软件管理(UML中称为实现视图)
- 左下——进程视图(Process View):侧重于系统的运行特性,主要关注与系统集成人员有关的非功能性需求,例如系统的性能和可用性等。进程视图强调并发性、分布性、系统集成性和容错能力,以及从逻辑视图中的主要抽象如何适合进程结构等,它也定义了逻辑视图中的各个类的操作具体是在哪一个线程中被执行的。进程视图可以描述成多层抽象,每个级别分别关注不同的方面。——性能可扩充性、吞吐量等(同UML)
- 右下——物理视图(Physical View):主要考虑系统工程人员如何把软件映射到硬件上,它通常要考虑到解决系统拓扑结构、系统安装和通信等问题。当软件运行于不同的物理节点上时,各视图中的构件都直接或间接地对应于系统的不同节点上。因此,从软件到节点的映射要有较高的灵活性,当环境改变时,对系统其他视图的影响最小化。——系统拓扑、安装、通信等(UML中称为部署视图)
- 中心——场景(Scenarios):场景的详细定义详见质量属性场景描述。可视为重要系统活动的抽象,它使四个视图有机联系起来,某种意义上说场景视图是最重要的需求抽象。在开发软件架构时帮助架构设计师找到构件及其相互关系。同时,架构设计师也可以用场景视图来分析一个特定的视图,或描述不同视图的构件之间是如何相互作用的。场景可以用文本表示,也可以用图形表示。(UML中为用例视图)
1.3 架构描述语言(ADL)
架构描述语言(Architecture Description Language,ADL)是一种为明确说明软件系统的概
念架构和对这些概念架构建模提供功能的形式化语言。它在底层语义模型的支持下,为软件系统的概念体系结构建模提供了具体语法和概念框架。如:Aesop、MetaH、C2、Rapide、SADL、Unicon等。
Unicon示例(运用极少,了解即可):
USES p1 PROTOCOL Unix-pipe USES sorter INTERFACE Sort-filter CONNECT sorter.output TO p1.source USES p2 PROTOCOL Unix-pipe USES printer INTERFACE Print-filter CONNECT sorter.input TO p2.sink
ADL的三个基本元素:
- 构件:计算或数据存储单元。(组件、组件接口)
- 连接件:用于构件之间交互建模的体系结构构造块及其支配这些交互的规则。
- 架构配置:描述体系结构的构件与连接件的连接图。
1.4 软件架构设计与生命周期
软件架构贯穿整个生命周期的,不同阶段的作用和意义不同,各阶段架构工作表现如下所示:
- 需求分析阶段:有利于各阶段参与者的交流,也易于维护各阶段的可追踪性。
- 设计阶段:关注最早和最多的阶段。
- 实现阶段:有效实现从软件架构设计向实现的转换。
- 构件组装阶段:可复用构件组装的设计能够提高系统实现的效率。
- 部署阶段:组织和展示部署阶段的软硬件架构、评估分析部署方案。
- 后开发阶段:主要围绕维护、演化、复用进行。
1.5 软件架构的复用
软件复用/重用(Reusability)是多次不同的软件开发过程中重复使用相同或相似【软件元素】(需求分析文档、设计过程、设计文档、程序代码、测试用例、领域知识)的过程。
软件架构复用是系统化的软件开发过程:开发一组基本的软件构件模块,以覆盖不同的需求/体系结构之间的相似性,提高系统开发的效率、质量和性能。
复用的历史发展线路:
- 结构化时代
- 函数库
- 面向对象时代
- 类库
- 框架【多个类的组合】
- 构件库
- 服务库
- 类库
复用的维度:
- 横向重用:重用不同应用领域中的软件元素,例如数据结构、分类算法和人机界面构建等。标准函数是一种典型的、原始的横向重用机制。
- 纵向重用:在一类具有较多公共性的应用领域之间进行软部件重用。纵向重用活动的主要关键点是域分析(根据应用领域的特征及相似性预测软部件的可重用性)。
软件架构复用的原因:减少开发工作、减少开发时间、降低开发成本、提高生产力、提高产品质量,更好的互操作性。
可复用的资产:需求、架构设计、元素、建模分析、测试、项目规划、过程+方法+工具、人员、样本系统、缺陷消除。
一般形式的复用:函数的复用、库的复用、面向对象开发中的类、接口和包的复用。
软件架构复用的基本过程:
- 构建/获取可复用的软件资产(复用前提)
- 管理可复用资产
- 使用可复用资产
2 软件架构风格 ⭐️⭐️⭐️⭐️⭐️☀️
重中之重!!!各种Web架构风格详见后述。
软件架构风格(Architecture Style):描述特定软件系统组织方式的惯用模式(组织方式描述了系统的组成构件和这些构件的组织方式;惯用模式则反映众多系统共有的结构和语义),定义了用于描述系统的术语表和一组指导构建系统的规则。
架构模式是软件设计中的高层决策,反映了开发软件系统过程中所作的基本设计决策,例如C/S结构;设计模式主要关注软件系统的设计,与具体的实现语言无关;惯用法则是实现时通过某种特定的程序设计语言来描述构件与构件之间的关系,例如C++语言中的引用-计数。
五大架构风格 | 子风格 |
---|---|
数据流风格 | 批处理、管道-过滤器 |
调用/返回风格 | 主程序/子程序、面向对象、分层架构 |
独立构件风格 | 进程通信、事件驱动系统(隐式调用) |
虚拟机风格 | 解释器、规则系统 |
仓库风格(以数据为中心) | 数据库系统、黑板系统、超文本系统 |
其他常见风格:闭环控制(过程控制)风格、C2风格……
2.0 软件架构案例分析总结 ☀️☀️
软件架构风格是描述某一类特定应用领域中软件系统组织方式和惯用方式。组织方式描述了系统的组成构件和这些构件的组织方式,惯用模式则反映众多系统共有的结构和语义。
- 管道-过滤器架构风格中,每个构件都有一组输入和输出,构件接受数据输入,经过内部处理,然后产生数据输出。这里的构件称为过滤器,构件之间的连接件称为数据流传输的管道。
- 主程序-子程序架构风格中,所有的计算构件作为子程序协作工作,并由一个主程序顺序地调用这些子程序,构件通过共享存储区交换数据。
- 面向对象架构风格的特征是将数据表示和基本操作封装在对象中。这种模式的构件是对象,对象维护自身表示的完整性,对象之间通过消息机制进行通信,对象交互时需要知道彼此的标识,通过对象之间的协作完成计算过程。
- 控制环路(过程控制)架构风格是将过程输出的指定属性维护在一个特定的参考值(设定点)。控制环路风格包括过程变量、被控变量、输入变量、操纵变量和设定点等构件,通过收集实际和理想的过程状态信息,并能调整过程变量使得实际状态趋于理想状态。
比较因素 | 管道-过滤器风格 | 数据仓库风格 |
---|---|---|
交互方式 | 顺序结构或有限的循环结构 | 星型 |
数据结构 | 数据流 | 文件或模型 |
控制结构 | 数据流驱动 | 业务功能驱动 |
扩展方法 | 接口适配 | 模型适配 |
【例】某软件公司为其新推出的字处理软件设计了一种脚本语言,专门用于开发该字处理软件的附加功能插件。为了提高该语言的编程效率,公司组织软件工具开发部门为脚本语言研制一套集成开发环境。软件工具开发部门根据字处理软件的特点,对集成开发环境进行了需求分析,总结出以下3项核心需求:
(1)集成开发环境需要提供对脚本语言的编辑、语法检查、解释、执行和调试等功能的支持,并要实现各种功能的灵活组合、配置与替换。
(2)集成开发环境需要提供一组可视化的编程界面,用户通过对界面元素拖拽和代码填充的方式就可以完成功能插件核心业务流程的编写与组织。
(3)在代码调试功能方面,集成开发环境需要实现在脚本语言编辑界面中的代码自动定位功能。具体来说,在调试过程中,编辑界面需要响应调试断点命中事件,并自动跳转到当前断点处所对应的代码。
针对上述需求,软件工具开发部门对集成开发环境的架构进行分析与设计,王工认为该集成开发环境应该采用管道-过滤器的架构风格实现,李工则认为该集成开发环境应该采用以数据存储为中心的架构风格来实现。公司组织专家对王工和李工的方案进行了评审,最终采用了李工的方案。
问题1:
请用200字以内的文字解释什么是软件架构风格,并从集成开发环境与用户的交互方式、集成开发环境的扩展性、集成开发环境的数据管理三个方面说明为什么最终采用了李工的设计方案。
问题2:
在对软件系统架构进行设计时,要对架构需求进行分析,针对特定需求选择最为合适的架构风格,因此实际的软件系统通常会混合多种软件架构风格。请对核心需求进行分析,说明为了满足需求(2)和(3),分别应采用何种架构风格,并概要说明采用相应架构风格后的架构设计过程。
【解】
问题1:
软件架构风格是指描述特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件和这些构件的组织方式,惯用模式则反映众多系统共有的结构和语义。
从集成开发环境与用户的交互方式看,用户通常采用交互式的方式对脚本语言进行编辑、解释执行与调试。在这种情况下,采用以数据存储为中心的架构风格能够很好地支持交互式数据处理,而管道-过滤器架构风格则对用户的交互式数据处理支持有限。
从集成开发环境的扩展性来看,系统核心需求要求实现各种编辑、语法检查、解释执行等多种功能的灵活组织、配置与替换。在这种情况下,采用以数据存储为中心的架构风格,以数据格式解耦各种功能之间的依赖关系,并可以灵活定义功能之间的逻辑顺序。管道-过滤器架构风格同样以数据格式解耦数据处理过程之间的依赖关系,但其在数据处理逻辑关系的灵活定义方面较差。
从集成开发环境的数据管理来看,集成开发环境需要支持脚本语言、语法树(用于检查语法错误)、可视化模型、调试信息等多种数据类型,并需要支持数据格式的转换。以数据存储为中心的架构将数据存储在统一的中心存储器中,中心存储器能够表示多种数据格式,并能够为数据格式转换提供各种支持。管道-过滤器架构风格通常只能支持有限度的数据格式,并且在数据格式转换方面的灵活性较差。
问题2:
为了满足需求(2),应该采用解释器架构风格。具体来说,需要:①为可视化编程元素及其拖拽关系定义某种语言,并描述其语法与语义;②编写解释器对该语言进行解释;③生成对应的脚本语言程序。
为了满足需求(3),应该采用隐式调用架构风格。具体来说,首先需要定义“断点在调试过程中命中”这一事件,并实现当断点命中后的屏幕定位函数。集成开发环境维护一个事件注册表结构,将该事件与屏幕定位函数关联起来形成注册表中的一个记录项。在调试过程中,集成开发环境负责监听各种事件,当“断点在调试过程中命中”这一事件发生时,集成开发环境查找事件注册表,找到并调用屏幕定位函数,从而实现脚本语言编辑界面与调试代码的自动定位。
2.1 数据流风格
数据流风格(Data Flow)的基本特点为数据驱动——前一步处理的结果是后一步的输入内容。有批处理、管道-过滤器两种子风格。
优点:
- 松耦合【高内聚-低耦合】
- 良好的可修改性——重用性(各处理单元独立且功能明确)、可维护性(结构简单)、可扩展性【标准接口适配】
- 良好的隐蔽性
- 支持并行
缺点:
- 交互性较差
- 复杂性较高
- 性能较差(例如每个过滤器都需要解析与合成数据)
典型实例:
- 传统编译器(C语言)
- 网络报文处理
子风格:
- 批处理序列(Batch Sequential):大量【整体】数据、无需用户交互。
- 管道-过滤器(Pipes and Filters):【流式数据】(例如流媒体)、弱用户交互。(结构如下图所示)
- 基本思想:把多个过滤器使用管道相联。输入某个构件,经过内部处理,产生数据输出。
2.2 调用/返回风格
调用/返回风格(Call/Return)是平日开发程序时最基础的风格。其发展过程与编程思想(面向过程 → 面向对象 → 面向服务)的发展基本一致。有主程序/子程序、面向对象、分层架构风格三种子风格
子风格:
- 主程序/子程序(Main Program and Subroutine):面向过程
- 面向对象(Object-oriented):对象的方法调用
- 分层架构(Layered System):层与层之间的方法调用。
2.2.1 分层架构概述
结构:
优点:
- 良好的可修改性——可维护性(参考三层解耦的作用)、可扩展性(支持递增设计)、重用性(只要接口不变即可用在其它处)
缺点:
- 并不是每个系统都方便分层
- 很难找到一个合适的、正确的层次抽象方法(效率损失)
- 不同层次之间耦合度高的系统很难实现
特点:
- 各个层次的组件形成不同功能级别的虚拟机
- 多层相互协同工作,而且实现透明
2.2.2 C/S、B/S、RIA架构
C/S(Client/Server)架构与B/S(Browser/Server)架构的发展历史:
- 2层C/S:胖客户端【业务逻辑】 ↔ 服务器【数据库】
- 升级维护困难
- 3层C/S:瘦客户端【仅界面】 ↔ 应用服务器【业务逻辑】 ↔ 服务器【数据库】
- 业务逻辑变化不再需要更新客户端
- 3层B/S:零客户端【浏览器】 ↔ WEB应用服务器【业务逻辑】 ↔ 服务器【数据库】
- 完全不需要客户端,升级维护容易
RIA(Rich Internet Applications)架构风格的优点:
- 反应速度快
- 易于传播
- 交互性强
2.2.3 分布式系统的逻辑计算层
分布式系统开发中,通常需要将任务分配到不同的逻辑计算层,共分为5层:
- 表示层:实现用户界面
- 表示逻辑层:执行为了生成数据表示而必须进行的处理任务,如输入数据编辑等
- 应用逻辑层:包括为支持实际业务应用和规则所需的应用逻辑和处理过,如信用检查、数据计算和分析等
- 数据处理层:包括存储和访问数据库中的数据所需的应用逻辑和命令,如查询语句和存储过程等
- 数据层:数据库中实际存储的业务数据
C/S系统开发时可以采用不同的分布式计算架构:
- 分布式表示架构:应用逻辑层、数据处理层、数据层仍放置于服务器,表示层、表示逻辑层放置于客户机(2层C/S)
- 分布式数据架构:数据层、数据处理层放置于服务器,应用逻辑层、表示逻辑层、表示层放置于客户机(2层C/S;服务器仅保留数据相关层)
- 分布式数据和应用架构:数据层、数据处理层放置于数据服务器,应用逻辑层放置在应用服务器上,表示层、表示逻辑层放置于客户机。(3层C/S)
2.3 独立构件风格
独立构件风格(Independent Components)与调用/返回风格的不同在于强调每一个构建都具有相对独立性(不直接调用;将紧耦合改为松耦合;例如绑定onclick()
)。有进程通信、事件驱动系统(隐式调用)两种子风格。
其中,事件管理器的事件管理机制(衔接“主函数”与“子函数”)如下图所示:
优点(构件的优点):
- 松耦合
- 良好的可修改性——可扩展性、重用性
缺点(较为罕见):
- 构件放弃了对系统计算的控制。一个构件触发一个事件时,不能确定其他构件是否会响应它。并且即使它知道事件注册了哪些构件的过程,也无法保证这些过程被调用的顺序。
- 数据交换的问题。
- 由于过程的语义必须依赖于被触发事件的上下文约束,关于正确性的推理存在问题。
特点:
- 系统由若干子系统构成且成为一个整体
- 系统有统一的目标
- 子系统有主从之分
- 每一子系统有自己的事件收集和处理机制
子风格:
- 进程通信 (Communicating Processes):略(进程相关内容详见操作系统-进程管理)
- 事件驱动系统(Event System)/隐式调用:通过所监听的事件来驱动系统运作
- 典型实例:
onclick()
;Windows操作系统UI(由点击等事件驱动)……
- 典型实例:
2.4 虚拟机风格
虚拟机风格(Virtual Machine)在日常开发中亦使用甚多,能够创建虚拟环境(用于沙盒类建造游戏等)。Java虚拟机是最常见的一种虚拟机(如下图所示),可以实现跨平台(“一次编写,到处运行”)。有解释器、规则系统两种子风格。
解释器(Interpreter)架构风格:构建一个解释器来解释并执行特定领域或问题领域的语言或规则。
- 结构组成:解释器引擎、被解释执行的程序、两个状态(程序执行的当前状态、解释器引擎的内部状态)
- 优点:可以灵活应对自定义场景。
- 缺点:复杂度较高。
- 适用场景:需要“自定义规则”的场合。(有时序要求、要求业务灵活组合等)
- 【典例】某公司欲开发一个漫步者机器人,用来完成火星探测任务。机器人的控制者首先定义探测任务和任务之间的时序依赖性,机器人接受任务后,需要根据自身状态和外界环境进行动态调整,最终自动完成任务。针对这些需求,该机器人应该采用虚拟机(解释器、规则系统)架构风格最为合适。
规则系统(Rule-based System)架构风格:加强版解释器,在解释器的基础上增加经验规则(知识性规则)。
- 结构组成:规则集、规则解释器、规则/数据选择、工作内存
- 优缺点:同解释器
- 适用场景:一般用在人工智能领域和DSS(决策支持系统)等信息系统中,非常适合专家系统(ES)。其他场合用解释器亦足够满足需求。
2.5 仓库风格
仓库风格又称以数据为中心(Data-centered)。存在一个用于存储数据的中间部件——仓库。有数据库系统、超文本系统、黑板系统等多种子风格。
子风格
- 数据库系统(Database System):以数据为中心
- 超文本系统(Hypertext System):略
- 黑板系统(Blackboard System)实质上只是在数据库系统上新增了触发机制(黑板上信息变动时触发数据源)。
【例】现代编译器主要关注编译过程和程序的中间表示,围绕程序的各种形态进行转化与处理。这种情况下,可以针对程序的各种形态构建数据库,通过中心数据库进行转换与处理。
以下着重介绍黑板系统。
结构:
优点:
- 良好的可修改性——可维护性、重用性(知识源)、可扩展性
- 仓库均具有风格良好的可扩展性:各应用以数据为中心,当需要扩展时只需新增数据结点即可,耦合程度相对较低。
- 容错性和健壮性
缺点:
- 测试困难
- 不能保证有好的解决方案
- 难以建立好的控制策略
- 低效
- 开发困难
- 缺少并行机制
特点:
- 在以数据为中心(数据库系统的特点)的基础上,使用中心数据触发业务逻辑部件
典型实例:
- 语音识别(非常适合这种复杂的应用场景)
- 模式识别
- 图像处理
- 知识推理
2.6 闭环控制(过程控制)风格
闭环控制(Closed-loop Control)架构风格又称过程控制,不属于5大风格,但应用甚多。
与开环风格相比(开环系统所发出的信息则不返回),闭环存在反馈环节,使得所发送的数据能够返回给比较器(判断是否达到预期)。如下图所示:
特点:
- 适合于嵌入式系统,用于解决简单闭环控制问题
- 不适合复杂场景
经典应用:
- 空调温控(电视机遥控器则是开环)
- 定速巡航
2.7 C2风格
C2(Component and Connector)架构风格实际上属于层次架构风格的一种,存在构件和连接件,连接件将构件进行相连。
C2架构的基本规则:
- 构件和连接件都有一个顶部和一个底部。
- 构件的顶部要连接到连接件的底部,构件的底部要连接到连接件的顶部,构件之间不允许直连。
- 一个连接件可以和任意数目的其他构件和连接件连接。
- 当两个连接件进行直接连接时,必须由其中一个的底部到另一个的顶部。(根据图进行理解)
2.8 模型驱动架构(MDA)
模型驱动架构(Model-Driven Architecture,MDA)起源于分离系统规约和平台实现的思想。
相关概念:
- 模型(Model):客观事物的抽象表示。
- 架构(Architecture):构成系统的部件、连接件及其约束的规约。
- 模型驱动(Model-Driven):使用模型完成软件的分析、设计、构建、部署、维护等各开发活动。
MDA的主要目标:Portability(可移植性),Interoperability(互通性),Reusability(可重用性)
MDA的3种核心模型:
- 平台独立模型(Platform Independent Models,PIM):具有高抽象层次、独立于任何实现技术的模型。
- 平台相关模型(Platform Specific Models,PSM):与某种特定实现技术紧密相连的模型。PIM会被变换成一个或多个PSM。
- 代码(Code):用源代码对系统的描述(规约)。每个PSM都将被变换成代码。
3 基于架构的软件设计(ABSD) ⭐️⭐️⭐️⭐️
基于架构的软件设计(Architecture-Based Software Design,ABSD)方法以构成软件架构的商业、质量和功能需求等要素来驱动整个软件开发过程,是一个自顶向下、递归细化的软件开发方法。软件系统的体系结构通过该方法得到细化,直到能产生软件构件和类。
架构设计是一个迭代过程,在建立软件架构的初期,首要任务是选择一个合适的架构风格(见前述),在此基础上,开发人员通过架构模型,可以获得关于软件架构属性(见后述)的理解,为将来的架构实现与演化过程建立了目标。
3.1 基本组成与作用
ABSD方法有三个基础:
- 第一个基础:功能分解。在功能分解中,ABSD方法使用已有的基于模块的内聚和耦合技术。
- 第二个基础:通过选择架构风格来实现质量和业务需求。
- 第三个基础:软件模板的使用。
相关组成及其作用:
- 视角与视图:从不同的视角来检查/描述软件架构,所以会有不同的视图。(另见架构“4+1”视图)
- 用例:用来捕获功能需求
- 质量属性场景:用来捕获质量需求。
3.2 基于架构的开发模型 ⭐️
开发过程分为6个阶段:
- 架构需求
- 需求获取(从需求库中)
- 标识构建:生成类图 → 对类进行分组 → 把类打包成构建
- 需求评审
- 架构设计:提出架构模型 → 映射构件 → 分析构件相互作用 → 产生架构 → 设计评审
- 一旦得到了详细的软件架构设计,需要邀请独立于系统开发的外部人员对系统进行评审。
- 一般来说,软件架构设计活动将已标识构件集成到软件架构中,设计这些构件,但不予以实现。
- 架构文档化
- 输出:架构规格说明、测试架构需求的质量设计说明书
- 文档的完整性和质量是软件架构成功的关键因素。
- 注意事项:
- 文档要从使用者的角度进行编写
- 必须分发给所有与系统有关的开发人员
- 必须保证开发者手上的文档是最新的,但更新不要过于频繁
- 架构文档中描述应该尽量避免不必要的重复
- 每次架构文档修改都应该记录进行修改的原则
- 架构复审
- 目的:标识潜在的风险,及早发现架构设计中的缺陷和错误
- 过程:通常会对一个可运行的最小化系统进行架构评估和测试。
- 架构实现:复审后的文档化的架构 → 分析与设计 → 构件实现 → 构件组装 → 系统测试
- 架构演化:需求变化归类 → 架构演化计划 → 构件变动 → 更新后的相互作用 → 构建组装与测试 → 技术评审 → 演化后的架构
总体流程如下图所示(0:M
、0:N
表示多轮迭代):
4 特定领域软件架构(DSSA) ⭐️⭐️⭐️
特定领域软件架构(Domain Specific Software Architecture,DSSA)以一个特定问题领域为对象,形成由领域参考模型、参考需求、参考架构等组成的开发基础架构,支持一个特定领域中多个应用的生成。
4.1 基本活动
DSSA基本活动及产出物:
- 领域分析:建立领域模型,领域模型描述领域中系统之间共同的需求,即领域需求
- 领域设计:获取特定领域软件架构(DSSA),DSSA描述领域模型中表示需求的解决方案
- 领域实现:依据领域模型和DSSA开发和组织可重用信息,并对基础软件架构进行实现
4.2 水平域与垂直域
从功能覆盖的范围角度理解DSSA中领域的含义有两种方法:
- 垂直域:定义了一个特定的系统族,导出在该领域中可作为系统的可行解决方案的一个通用软件架构。
- 水平域:定义了在多个系统和多个系统族中功能区域的共有部分,在子系统级上涵盖多个系统(族)的特定部分功能。
在特定领域架构中,垂直域关注的是与行业相关的,聚焦于行业特性的内容,而水平域关注的是各行业共性部分的内容。
4.3 领域分析机制
参与DSSA的人员:
- 领域专家:有经验的用户、从事该领域中系统的需求分析、设计、实现以及项目管理的有经验的软件工程师等。
- 领域专家的主要任务包括提供关于领域中系统的需求规约和实现的知识。(是出意见的人,下面3位是干活的人)
- 领域分析人员:应由具有知识工程背景的有经验的系统分析员来担任。
- 领域设计人员:应由有经验的软件设计人员来担任。
- 领域实现人员:应由有经验的程序设计人员来担任。
4.4 建立过程
建立DSSA的过程:
- 定义领域范围
- 定义领域特定的元素
- 定义领域特定的设计和实现需求约束
- 定义领域模型和架构
- 产生、搜集可复用的产品单元
最后回归第一步,不断求精。这是一个并发的、递归的、反复的、螺旋型的过程。(参考螺旋模型)
DSSA的三层次模型:
- 领域开发环境:领域架构师
- 领域特定应用开发环境:应用工程师
- 应用执行环境:操作员
5 软件架构评估 ⭐️⭐️⭐️⭐️
- 各种架构评估方法(如ATAM)不是一种精确的评估工具。
- 三问
- 为什么要进行架构评估?
- 架构评估到底评什么?
- 架构评估怎么评?
- ——依据:软件质量属性
5.1 软件质量属性 ⭐️⭐️⭐️⭐️⭐️☀️☀️
常见的质量属性(非功能性指标):
- 性能(Performance):系统的响应能力,即要经过多长时间才能对某个事件做出响应,或者在某段时间内系统所能处理的事件的个数。
- 典例:① 同时支持1000并发;② 响应时间小于1s;③显示分辨率达到4K
- 代表参数:响应时间、吞吐量
- 架构策略:优先级队列、资源调度
- 可靠性(Reliability):软件系统在应用或系统错误面前,在意外或错误使用的情况下维持软件系统的功能特性的基本能力。(详见可靠性分析)
- 子属性:
- 容错
- 健壮性(Robustness):在处理或环境中,系统能够承受压力或变更的能力。
- 子属性:
- 可用性(Availability):系统能够正常运行的时间比例。(可靠性的衍生;经常用两次故障之间的时间长度或在出现故障时系统能够恢复正常的速度来表示)
- 典例:① 主服务器故障,1分钟内切换至备用服务器;② 系统故障,1小时内修复;③ 系统支持7×24小时工作
- 代表參数:故障间隔时间
- 架构策略:主动冗余、心跳线(Ping/Echo)
- 安全性(Security):系统在向合法用户提供服务的同时能够阻止非授权用户使用的企图或拒绝服务的能力。
- 特性(至少4种,具体实现详见安全架构-安全模型):
- 机密性:信息不泄露给未授权的用户
- 完整性:防止信息被篡改
- 不可否认性:不可抵赖
- 可控性:对信息的传播及内容具有控制的能力
- 典例:① 可抵御SQL注入攻击;② 对计算机的操作都有完整记录;③ 用户信息数据库授权必须保证99.9%可用
- 架构策略:限制访问、追踪审计、冗余(同可用性,但优先提高可用性)
- 特性(至少4种,具体实现详见安全架构-安全模型):
- 可修改性(Modifiability):能够快速地以较高的性能价格比对系统进行变更的能力。(修改的方便程度)
- 子属性:
- 可维护性(Maintainability)
- 可扩展性(Extendibility)
- 结构重组(Reassemble)
- 可移植性(Portability)/复用性/重用性(Reusability):详见构件与中间件技术-软件复用
- 典例:① 更改系统报表模块,必须在2人周内完成;② 对Web界面风格进行修改,修改必须在4人月内完成
- 架构策略:运行时注册、接口-实现分离、信息隐藏
- 子属性:
- 功能性(Functionality):系统所能完成所期望工作的能力。
- 可变性(Changeability):体系结构经扩充或变更成为新体系结构的能力。
- 互操作性(Inter-operation):系统与外界或系统与系统之间的相互作用能力。
其他属性:
- 易用性(Usability):衡量用户使用一个软件产品完成指定任务的难易程度。
- 典例:①界面友好;② 新用户学习使用系统时间不超过2小时
- 可测试性(Testability):软件发现故障并隔离、 定位其故障的能力特性, 以及在一定的时间和成本前提下,进行测试设计、测试执行的能力。
- 典例:提供远程调试接口,支持远程调试
- 架构策略:记录-回放
5.2 系统架构设计中的非功能性需求 ☀️☀️
软件架构更关注非功能性需求:
- 系统性能需求(Performance Requirements):指响应时间、吞吐量、准确性、有效性、资源利用率等与系统完成任务效率相关的指标。可靠性、可用性等属性归为此类。
- 安全性需求(Security Requirements):系统向合法用户提供服务并阻止非授权用户使用服务方面的系统需求。
- 操作性需求(Operational Requirements):与用户操作使用系统相关的一些需求。
- 文化需求(Cultural Requirements):带有文化背景因素的系统需求。
5.3 架构评估中的4个“点” ☀️☀️
以下4个“点”通常属于功能性指标:
- 敏感点(Sensitivity Point):为了实现某种特定的质量属性,一个或多个构件(和/或构件之间的关系)的特性。(该特性会对最终系统有影响;设计策略)
- 权衡点(Tradeoff Point):影响多个质量属性的特性,是多个质量属性的敏感点。(如图所示,两头属性经常朝相反趋势变动)
- 风险点:架构设计中潜在的、存在问题的架构决策所带来的隐患。【可能】
- 非风险点:不会带来隐患。一般以“xxx要求是可以实现(或接受)”的方式表达。
【例】常见情形:
- 对交易请求处理时间的要求将影响系统的数据传输协议和处理过程的设计——敏感点
- 假设每秒中用户交易请求的数量是10个,处理请求的时间为30毫秒,则“在1秒内完成用户的交易请求”这一要求是可以实现的——非风险点
- 目前对系统信用卡支付业务逻辑的描述尚未达成共识,这可能导致部分业务功能模块的重复,影响系统的可修改性——风险点
- 更改加密的级别将对安全性和性能产生影响——权衡点
- ……
5.4 架构评估方法
常用的软件架构评估方法:
- 基于调查问卷/检查表的方式
- 基于度量的方式
- 基于场景的方式(最常用)
5.4.1 质量属性场景描述
场景(Scenarios)是从风险承担者的角度与系统交互的简短描述。
场景可从6个方面进行描述:
- 刺激源(Source)
- 刺激(Stimulus)
- 制品(Artifact)
- 环境(Environment)
- 响应(Response)
- 响应度量(Measurement)
性能场景示例:
3种基于场景的评估方法:
- 软件架构分析法:最初关注可修改性,后扩充到可移植性、可扩充性等其他属性。
- 架构权衡分析法:在SAAM的基础上发展而来,主要针对性能、实用性(可用性,Availability)、安全性、可修改性。
- 成本效益分析法(Cost-Benefit Analysis Method,CBAM):在ATAM基础上建立的、软件的“经济”模型。
5.4.2 软件架构分析法(SAAM)
软件架构分析法(Software Architecture Analysis Method,SAAM):最初用于分析架构可修改性,后扩展到其他质量属性。
方法:
- 主要输入:问题描述、需求说明、架构描述
- 分析过程:场景开发、架构描述、单个场景评估、场景交互评估(单个架构评估)、总体评估(比较多个架构)
5.4.3 架构权衡分析法(ATAM)
架构权衡分析法(Architecture Tradeoff Analysis Method,ATAM):在SAAM的基础上发展而来,主要针对性能、实用性(可用性,Availability)、安全性、可修改性。在系统开发之前,对这些质量属性进行评价和折中。ATAM需要对软件质量属性进行优先级排序。
与SAAM不同的是,ATAM分为4个阶段(行动计划),如图所示:
- 第一阶段:场景和需求收集(该阶段与SAAM相同)
- 收集场景
- 收集需求/约束/环境
- 第二阶段:架构视图和场景实现
- 描述架构视图
- 实现场景
- 第三阶段:属性模型构造和分析
- 特定属性分析(优秀的单一理论)
- 第四阶段:折中
- 标志敏感度
- 标志折中
5.5 质量效用树 ☀️☀️
质量效用树(Utility Tree)是对质量属性进行分类、权衡、分析的架构分析工具,主要关注系统的性能、可修改性、可用性和安全性四个方面。可以直观地展现出项目中一系列关键场景中的因素。
实为本章全部内容的综合表示。
【例】某网上购物电子商务公司拟升级正在使用的在线交易系统,以提高用户网上购物在线支付环节的效率和安全性。在系统的需求分析与架构设计阶段,公司提出的需求和关键质量属性场景如下:
(a)正常负载情况下,系统必须在0.5秒内对用户的交易请求进行响应;
(b)信用卡支付必须保证99.999%的安全性;
(c)对交易请求处理时间的要求将影响系统的数据传输协议和处理过程的设计;
(d)网络失效后,系统需要在1.5分钟内发现错误并启用备用系统;
(e)需要在20人月内为系统添加一个新的CORBA中间件;
(f)交易过程中涉及到的产品介绍视频传输必须保证画面具有600*480的分辨率,20帧/秒的速率;
(g) 更改加密的级别将对安全性和性能产生影响;
(h)主站点断电后,需要在3秒内将访问请求重定向到备用站点;
(i)假设每秒用户交易请求的数量是10个,处理请求的时间为30毫秒,则“在1秒内完成用户的交易请求”这一要求是可以实现的;
(j)用户信息数据库授权必须保证99.999%可用;
(k)目前对系统信用卡支付业务逻辑的描述尚未达成共识,这可能导致部分业务功能模块的重复,影响系统的可修改性;
(I)更改Web界面接口必须在4人周内完成;
(m)系统需要提供远程调试接口,并支持系统的远程调试。
在对系统需求和质量属性场景进行分析的基础上,系统的架构师给出了三个候选的架构设计方案。公司目前正在组织系统开发的相关人员对系统架构进行评估。
问题1:在架构评估过程中,质量属性效用树(Utility Tree)是对系统质量属性进行识别和优先级排序的重要工具。请给出合适的质量属性,填入下图中(1)、(2)空白处;并选择题干描述的(a)~(m),填入(3)~(6)空白处,完成该系统的效用树。
问题2:在架构评估过程中,需要正确识别系统的架构风险、敏感点和权衡点,并进行合理的架构决策。请用300字以内的文字给出系统架构风险、敏感点和权衡点的定义,并从题干(a)~(m)中各选出1个对系统架构风险、敏感点和权衡点最为恰当的描述。
【解】
问题1:由(e)、(d)分别可得(1)为可修改性,(2)为可用性。(3)为(f),(4)为(j),(5)为(h),(6)为(b)。
问题2:系统架构风险是指架构设计中潜在的、存在问题的架构决策所带来的隐患。敏感点是指为了实现某种特定的质量属性,一个或多个构件所具有的特性。权衡点是影响多个质量属性的特性,是多个质量属性的敏感点。
6 软件产品线 ⭐️⭐️⭐️
软件产品线(Software Product Line)是指具有一组可管理的公共特性的软件密集性系统的合集。如下图所示,其中红圈部分即为软件产品线:
特点:
- 核心资源
- 产品集合
- 过程驱动
- 特定领域
- 技术支持
- 以架构为中心
软件产品线的双生命周期模型如下图所示:
软件产品线的建立方式:跨度上有演化式和革命式,建立过程中还应考虑基于现有产品还是全新产品线
- 将现有产品演化为产品线
- 用软件产品线替代现有产品集
- 全新软件产品线的演化
- 全新软件产品线的开发
软件产品线建立方式 | 演化方式 | 革命方式 |
---|---|---|
基于现有产品 | 基于现有产品架构设计产品线的架构,经演化现有构件,开发产品线构件 | 核心资源的开发基于现有产品集的需求和可预测的、将来需求的超集 |
全新产品线 | 产品线核心资源随产品新成员的需求而演化 | 开发满足所有预期产品线成员的需求的核心资源 |
组织结构类型:
- 设立独立的核心资源小组
- 不设立独立的核心资源小组
- 动态的组织结构
要成功实施产品线,主要取决于以下因素:
- 对该领域具备长期和深厚的经验
- 一个用于构建产品的好的核心资源库
- 好的产品线架构
- 好的管理(软件资源、人员组织、过程)支持
7 构件与中间件技术 ⭐️⭐️⭐️
构件化思想详见:软件工程-软件过程模型-构件组装模型、CBSE
7.1 面向构件的编程(COP)
面向构件的编程(Component Oriented Programming,COP)关注于如何支持建立面向构件的解决方案。一个基于一般OOP风格的COP定义如下(Szyperski,1995):
面向构件的编程需要下列基本的支持:
- 多态性(可替代性)
- 模块封装性(高层次信息的隐藏)
- 后期的绑定和装载(部署独立性)
- 安全性(类型和模块安全性)
在基于构件的开发中,构件包含并扩展了模块化程序设计中子程序、面向对象系统中对象或类和系统模型中包的思想,它是系统设计、实现和维护的基础。构件是通过接口访问服务的一个独立可交付的功能单元。
系统构件组装过程分为3个不同的层次:
- 定制(Customization):根据特定需求对构件进行个性化的调整或修改。
- 集成(Integration):将多个定制好的构件组合成一个完整的软件系统。
- 扩展(Extension):在现有软件系统的基础上增加新的功能或构件。
7.2 构件的复用
编写基于构建的开发方法相关案例分析/论文时可参考以下构件复用步骤:
- 检索与提取构件
- 检索方法:
- 基于关键字的检索
- 特点:树形或有向无回路图结构(如上图所示)
- 刻面检索法
- 特点:利用刻面(Facet)描述构件执行的功能、被操作的数据、构件应用的语境或任意其他特征
- 刻面示例:应用领域、使用环境、功能
- 超文本检索法
- 特点:按照人类的联想思维方式任意跳转到包含相关概念或构件的文档
- 基于关键字的检索
- 检索方法:
- 理解与评价构件
- 要点:
- 要复用构件,准确地理解构件至关重要。特别是对构件修改使用时。
- 为达到目的,必须要求构件的开发过程遵循公共标准。
- 一般构件库的文档中全面而准确地说明以下内容:
- 构件的功能与行为
- 相关的领域知识
- 可适应性约束条件与例外情形
- 可以预见的修改部分及修改方法
- 要点:
- 修改构件
- 要点:
- 理想状态是直接复用构件库中现成的构件,但大多数情况下,必须对构件进行或多或少的修改,以应对新需求。
- 为了减少构件修改的工作量,要求开发人员尽量使构件的功能、行为和接口设计更为抽象化、通用化和参数化。这样,复用者即可通过对实参的选取来调整构件的功能或行为。如果这种调整仍不足以使构件适用于新系统,复用者就必须借助设计信息和文档来修改构件。
- 构件库中若无可修改使用的构件,则按新需求开发构件,并存入构件库。
- 要点:
- 组装构件
- 组装的3种方式:
- 基于功能的组装:采用子程序调用和参数传递的方式将构件组装起来。
- 基于数据的组装:仍然是传统的子程序调用与参数传递。但它所依赖的软件设计方法不再是功能分解,而是面向数据的设计方法,例如,Jackson系统开发方法。
- 面向对象的组装:如果从类库中检索出来的基类能够完全满足新系统的需求,则可以直接应用。否则,必须以基类为父类,生成相应的子类,以满足新系统的需求。
- 构件组装失配问题:
- 由构件引起的失配,包括由于系统对构件基础设施、构件控制模型和构件数据模型的假设存在冲突引起的失配;
- 由连接子引起的失配,包括由于系统对构件交互协议、连接子数据模型的假设存在冲突引起的失配;
- 由于系统成分对全局体系结构的假设存在冲突引起的失配等。要解决失配问题,首先需要检测出失配问题,并在此基础上通过适当的手段消除检测出的失配问题。
- 组装的3种方式:
7.3 构件标准
常见的3个构件标准:
- CORBA
- J2EE中的EJB
- 会话Bean:实现业务逻辑,负责完成服务端与客户端的交互
- 实体Bean:实现O/R映射(对象关系映射,Object-Relational Mapping),简化数据库开发工作
- 消息驱动Bean:处理并发与异常访问
- DNA 2000
J2EE 核心组成:
- 容器:Applet Container、Application Container、Web Container、EJB Container
- 组件:Applet、Application、JSP/Servlet、EJB
CORBA(Common Object Request Broker Architecture)是由对象管理组织(OMG)制定的一种面向对象的构件重用标准,旨在提高软件构件的重用性和互操作性。
CORBA解决了远程调用问题(例如客户端与服务器不在同一局域网),在本地设置对象引用,使得能够像调用本地资源般调用远程资源(逻辑上),而底层实现均交予COBRA实现。
重要组成部分:
- 伺服对象(Servant):CORBA对象的真正实现,负责完成客户端请求。
- 对象适配器(Object Adapter)POA:用于屏蔽ORB内核的实现细节,为服务器对象的实现者提供抽象接口,以便他们使用ORB内部的某些功能。
- 对象请求代理(Object Request Broker):解释调用并负责查找实现该请求的对象,将参数传给找到的对象,并调用方法返回结果。客户方不需要了解服务对象的位置、通信方式、实现、激活或存储机制。
OMG基于CORBA基础设施定义了4种构件标准:
- 实体(Entity)构件:需要长期持久化并主要用于事务性行为,由容器管理其持久化。
- 加工(Process)构件:同样需要容器管理其持久化,但没有客户端可访问的主键。
- 会话(Session)构件:不需要容器管理其持久化,其状态信息必须由构件自己管理。
- 服务(Service)构件:是无状态的。
7.4 中间件基本概念
中间件(Middleware)是一种独立的系统软件或服务程序,可以帮助分布式应用软件在不同的技术之间共享资源。
中间件的作用:
- 负责客户机与服务器之间的连接和通信,以及客户机与应用层之间的高效率通信机制。
- 提供应用的负载均衡和高可用性、安全机制与管理功能,并提供交易管理机制来保证交易的一致性。
- 提供应用层不同服务之间的互操作机制,以及应用层与数据库之间的连接和控制机制。
- 提供多层架构的应用开发和运行的平台,以及应用开发框架,支持模块化的应用开发。
- 屏蔽硬件、操作系统、网络和数据库的差异。
- 提供一组通用的服务去执行不同的功能,避免重复的工作和使应用之间可以协作。
《系统架构核心知识(3):软件架构设计》有1条评论