软件设计与体系结构
术语表:
文章目录
- 软件设计与体系结构
- 软件构架
- 构架与环境
- 质量属性(quality attribute)
- 构架模式
- 设计模式
- 架构设计方法
- 构架评估Architecture Evaluation
- 软件产品线 Software Product Lines
软件构架
软件构架(software architecture)是什么:一个系统的软件架构是推理系统所需的一组结构,包括软件元素、它们之间的关系以及两者的属性
作用是软件想法和软件产品之间的桥梁。
说法:
Architecture is a set of software structure 架构是一组软件结构
Architecture is an abstraction 架构是一种抽象
In modern systems, elements interact with each other by means of interface 在现代系统中,元素相互作用 通过接口相互连接
Interface partition the details of an element into public and private parts 接口将元素的详细信息划分为公共部分和私有部分
Architecture is concerned with the public side of interface 架构关注的是接口的公共端
This abstraction is essential to tame the complexity of a system 这种抽象对于控制系统的复杂性至关重要
Every software has a software architecture 每个软件都有一个软件架构
Every system can be shown to comprise elements and relations among them每个系统都可以被证明由元素及其之间的关系组成
Architecture can exist independently of its description(source code) or specification(document) 架构可以独立于其描述(源代码)或规范(文档)而存在
Architecture includes behavior 架构包括行为
The behavior of each elements is part of the architecture 元素的行为是架构的一部分
The behavior can be used to reason about the system 该行为可以用来推理 系统
The behavior include the function of system and the interact of elements 行为包括系统的功能和要素的交互
Architecture need explanation 架构需要解释
Not all architectures are good architecture 并非所有架构都是好架构
The definition is indifferent as to whether the architecture for a system is a good one or a bad one 该定义对于系统架构是好是坏无关紧要
An architecture may permit or preclude a system’s achievement of its behavioral, quality attribute and requirements 架构可以允许或阻止系统实现其行为、质量属性和需求
Therefore, the architecture design and evaluation is important 因此,架构设计和评估非常重要
软件构架分类
结构和视图
一个结构(structure)是一组元素本身及其关系,因为它们存在于软件或硬件中
一个视图( view) 是一组连贯的架构元素的表示(representation),由系统利益相关者(stakeholders)编写和阅读
构架师设计结构,构架师文档化这些结构的视图,视图是结构的表示
Module structure模块结构
模块结构将系统划分为实施单元模块被分配了具体的计算职责,是工作分配的基础。模块结构是静态结构(static structure) 它支持可修改性
模块结构是系统的组成结构
模块结构体现了如何由一组模块构建系统的决策
它用UML图来表示:类图、对象图、包图等
模块结构回答问题:
每个模块的主要功能职责是什么
允许使用哪些其他元素
它使用并依赖什么软件
泛化或专门化(generalization or specialization)与其他模块相关
包含:
- 分解结构Decomposition structure:该结构显示了模块如何分解为更小的模块。元素:模块。关系:是一个子模块。受影响的质量属性:可修改性
- 使用结构Uses structure:该结构显示模块如何使用其他模块或模块子集。元素:模块。关系:用途(即需要正确存在)。受影响的质量属性:子集性、可扩展性
- 分层结构Layer structure:层提供一组内聚的服务。层允许以严格管理的方式使用其他层。元素:层。关系:使用以下服务。受影响的质量属性:可移植性
- 类结构Class structure:相似集合的推理行为。元素:类、对象。关系 :是一个实例,共享访问方法。受影响的质量属性:可重用性、可扩展性
- 数据模型结构Data model structure:数据模型用数据实体及其关系来描述静态信息结构。元素:数据实体。关系:数据概括、专门化。受影响的质量属性:可修改性
Component-and-connector(C&C) structure组件和连接器结构
C&C 结构侧重于元素在运行时相互交互以执行系统功能的方式。这是一个动态结构(dynamic)。它支持性能、安全性
组件和连接器结构代表系统的运行时属性
C&C 结构体现了关于如何将系统构建为一组具有运行时行为和交互(连接器)的元素的决策
它用UML图来表示:序列图、活动图、状态图等
元素:运行时组件 例如:计算单元、服务、客户端、对等点和过滤器等。
关系:连接器例如:调用返回、进程同步运算符、协议和管道等。
C&C结构回答问题:
主要有哪些 执行组件
共享数据存储有哪些
系统的哪些部分被复制
数据如何通过系统进行处理
系统的哪些部分可以并行运行
包含:
- 服务结构(Service structure):该结构显示了如何发现和提供服务。元素:服务、注册表。关系:同时运行、排除、先于。受影响的质量属性:互操作性、可修改性
- 并发结构(Concurrency structure):这种结构决定了并行的机会以及可能发生资源争用的位置。元素:进程、线程。关系:可以并行运行。受影响的质量属性:性能、可用性
Allocation structure分配结构
分配结构将软件结构映射到系统环境例如:分配给文件的模块、组件部署到硬件上、将工作分配给团队。它支持性能
软件系统与其环境(environment)之间的关系
分配结构体现了系统如何与其环境中的非软件结构相关的决策(embody decisions)
它用UML图来表示:部署图、组件图等。
要素:模块、环境要素 例如:模块、组件、文件、硬件等。关系:地图元素包括:模块Module(静态)和组件Component(动态)
分配结构回答问题:
每个软件元素在什么处理器上执行
在开发、测试和系统构建过程中,每个元素都存储在哪些文件目录中?
开发团队的分配是什么?
包含:
- 部署结构Deployment structure:该结构显示了如何将软件分配给硬件元素 : 组件、硬件元件。关系:分配至、迁移至。受影响的质量属性:性能、安全性、可用性
- 实现结构Implementation structure:该结构显示了软件元素如何映射到文件结构。元素:模块、文件结构。关系:存储。受影响的质量属性:开发效率
- 工作分配结构Work assignment structure:这种结构将责任分配给执行该任务的团队。元素:模块、组织单位。关系:分配给。受影响的质量属性:开发效率
系统、企业和软件架构
系统架构(System architecture)将功能映射到硬件和软件上系统架构涉及整个系统,包括硬件、软件和人类
企业架构(Enterprise architecture)是对组织流程、信息流、人员和子单元的结构和行为的描述
系统和企业架构为软件架构提供环境(environments)和约束(constraints)
软件架构必须存在于系统和企业内部
架构之间的关系
这些结构中的每一个都提供了系统的不同视角(different perspectiv)和设计处理(design handle on)
这些结构是相关的(dependent),一个结构的元素将与其他结构的元素相关
个别项目有时会考虑一种结构占主导地位(one structure dominant)并铸造其他结构
构架时的建议
- 单个建筑师或小组被确定为领导者
- 必须具有系统技术要求和明确的、优先考虑的定性属性(qualitative properties)
- 架构必须使用所有人都能理解的商定符号进行详细记录
- 评估架构提供系统重要质量属性的能力
- 架构应该允许创建一个骨架系统(skeletal system),在该系统上功能可以逐步增长
- 使用信息隐藏、关注点分离和定义良好的接口的定义良好的功能模块
- 应使用众所周知的架构模式和针对每个属性的策略来实现质量属性
- 永远不要依赖商业产品或工具的特定版本
- 将数据生产者与数据消费者分开(Separate)
- 不要期望模块和组件之间存在一对一的对应关系(one-to-one correspondence)
- 每个进程都应该编写为可以轻松更改对特定处理器的分配,甚至可以更改运行时
- 该架构应该具有少量的组件交互方式。系统应该以同样的方式做同样的事情。这将有助于提高可理解性、减少开发时间、提高可靠性。
- 该架构应包含一组特定的资源争用区域,明确指定并维护其解决方案。
构架与环境
影响构架的背景因素(contexts)
影响构架的背景因素包括:
- 技术:软件架构在系统中扮演什么技术角色
- 项目生命周期:架构如何与开发生命周期的其他阶段相关
- 业务(Business):如何影响业务
- 专业(Professional):架构师在组织或项目中的角色是什么
所有上下文都会影响(impact)软件架构
架构师面临的挑战是设想(envision)在他们的环境中可能会发生什么变化,并在设想的变化发生时采用机制来保护系统及其发展
适应上下文(Adapt the context)
构架如何受到影响:业务、技术、项目生命周期通过利益相关者间接影响构架师,专业直接影响构架师,而构架师影响架构,从而决定系统结果。
技术背景(Technical)
技术背景是影响架构实现系统质量属性的第一个因素
包括了:质量属性和技术环境
质量属性的影响
架构将抑制或促进(inhibit or enable)系统质量属性的实现
您可以通过架构来预测(predict)系统质量的许多方面
架构使您能够更轻松地推理和管理变更(manage change)
需求决定架构,架构决定系统结果
技术环境的影响
瓦萨号的教训:
-
成功的架构实践(Successful architectural practices)很重要。从而帮助建立当今的技术竞争环境
-
在构建任何系统之前评估架构(assess an architecture)的方法,以降低风险
-
增量架构(incremental architecture-based development)的开发技术,以发现设计缺陷
项目生命周期( Project Life-Cycle Context)
架构涉及到项目生命周期中的一些流程(processes)和活动(activities)
流程的影响
软件开发流程主要有四种:瀑布,迭代,敏捷,模型驱动开发
开发流程(processes)home at 架构,架构 包括 开发活动(activities)
活动的影响
- 制作业务案例;业务案例通过预测它们将如何影响组织来帮助组织做出决策:寻求新的商业机会评估机会的预期成本、收益和风险创建业务案例可以更广泛地评估系统的市场需求。架构师能够帮忙解答一下问题:成本是多少市场是什么上市时间和使用寿命是多少?是否需要与其他系统接口有系统限制吗
- 了解需求;了解架构上的重要需求是设计架构的开始。您可以通过方法获取需求:面向对象的分析;有限状态机模型;以前的系统;创建原型。
- 创建或选择架构(原则);创建或选择架构的原则是概念完整性(conceptual integrity)。概念完整性是健全系统设计的关键。只有少数人齐心协力设计系统架构才能实现概念完整性
- 记录架构;架构是项目设计的支柱(backbone)。必须清楚、明确地传达给所有利益相关者。架构文档应该内容丰富、明确且可读 由许多具有不同背景的人
- 分析或评估架构;在竞争设计中进行选择是建筑师面临的最大挑战之一。评估架构所支持的质量对于确保从该架构构建的系统满足利益相关者的需求至关重要(ATAM 方法)
- **基于该架构的系统实现与测试;**让开发人员忠于架构很重要。架构师帮助开发人员符合架构:1.与开发商沟通 2.详细记录的架构并进行传播(disseminated) 3.设计清晰且接地气(ground-level)
- 确保实施符合架构 在维护阶段,文档化的架构必须与实际架构同步
业务(Business)
架构和系统并不是轻率构建的。它们服务于一些商业目的。
业务影响分为业务目标(business goal)和开发组织(development organization)
业务目标的影响
创建系统是为了满足一个或多个组织的业务目标
开发组织希望:1.赚取利润 2.占领市场 3.更好地完成工作 4.保持员工有酬就业 5.让股东高兴
业务目标直接影响质量属性需求和架构,而质量属性需求决定架构。
开发组织的影响
组织对业务目标的影响又对架构产生影响:
- 组织投资于资产
- 组织对基础设施进行长期商业投资
- 组织结构可以塑造软件架构,反之亦然。
不同的组织(如大公司、小公司、学校、军队等)开发不同时效、不同要求的产品,对架构产生影响。
构架师的专业背景(Professional)
建筑师需要更多的技能和知识:1.沟通技巧(职责)2. 技术知识(最新知识,如:模式、网络、云、移动等)
经验;建筑师的教育和培训,接触成功的建筑模式;接触过运行特别差或特别好的系统
利益相关者对架构的影响
不同的利益相关者对系统的关注点不同,也会对架构造成不同的影响
利益相关者:
- 架构师:负责架构及其文档的开发。兴趣:在竞争需求和设计方法之间进行谈判和权衡。提供架构满足其要求的证据
- 业务经理:负责拥有系统的业务/组织实体的运作。兴趣:了解架构满足业务目标的能力
- 客户(Customer):支付系统费用并确保其交付。客户通常代表最终用户或代表最终用户。兴趣:确保交付所需的功能和质量;衡量进展;估算成本
- 用户(User):系统的实际最终用户。可能存在不同类型的用户,例如管理员。兴趣:使用架构文档检查是否正在交付所需的功能和质量
- 实施者(Implementer):负责根据设计、需求和架构开发特定元素。兴趣:了解开发活动中不可侵犯的限制(constraints)和可利用的自由
构架影响什么
架构会影响那些影响它们的因素:技术背景;项目背景;业务背景;专业背景
- 技术背景:该架构可以让客户有机会以更可靠、及时和经济的方式接收系统,从而影响利益相关者对下一个系统的需求。软件产品线对于不能如此灵活地满足其需求的客户也有同样的影响。
- 项目背景:架构影响开发组织的结构。架构规定了作为开发项目结构基础的软件单元
- 业务背景:从架构构建的成功系统可以使公司在特定市场领域站稳脚跟。该架构可以为类似系统的高效生产和部署提供机会。
- 专业背景:成功构建的系统将来会产生以相同方式构建的类似系统。另一方面,失败的架构不太可能被选择用于未来的项目。无论如何,无论成功还是失败,构建一个系统都是丰富架构师的经验的。
受环境和反馈机制影响的架构称为架构影响循环(Architecture Influence Cycle ( AIC ))
用哲学的话来说就是,技术、项目周期、业务、专业能力影响构架,而构架的实施反作用于其影响因素。
质量属性(quality attribute)
开发中质量属性优先于功能
系统经常被重新设计并不是因为功能有缺陷
系统的更换通常是由于质量属性差造成的
架构是软件创建中可以满足质量要求的首要位置
质量属性定义 (QA)是系统的可测量或可测试的属性,用于指示系统满足利益相关者需求的程度。质量属性,用于根据利益相关者感兴趣的某些维度来衡量产品的优点
架构如何满足需求
- 功能需求:分配(assigning)适当的职责(responsibilities)顺序来满足功能需求
- 质量属性需求:架构中设计的各种结构,特别是行为和交互结构(behavior and interaction structure),满足质量属性要求
- 约束(constraint):接受设计决策并将其与其他受影响的设计决策进行协调来满足约束
功能和架构
功能并不决定(determine)架构
尽管功能独立(independent)于任何特定的结构,但功能是通过将职责分配(assigning responsibilities)给体系结构元素(elements)来实现的。
当其他质量属性很重要时,架构会限制这种分配
质量属性的注意事项
质量属性与功能相关 The quality attributes relate to the functionality
功能具有很多可以用于衡量的品质。There are many qualities with respect to a function.
功能描述了系统的功能,质量描述了系统执行其功能的情况。 Function describes what the system does and quality describes how well the system does its function
有时,功能和品质是天然联系在一起的。Sometimes, the function and quality are naturally associated.
责任比功能或质量更普遍。The responsibility is more general than the function or qualit
三个问题:
- 定义和属性不可测试(testable)
- 讨论通常集中于特定关注点属于哪种质量
- 每个属性社区都开发了自己的词汇表
使用质量属性场景(quality attribute scenarios)作为表征质量属性的手段解决前两个问题
质量属性的分类:1.在运行时(at runtime)的一些属性,例如可用性、性能或可用性(availability, performance, or usability)。2.系统开发(development of the system)的一些属性,例如可修改性或可测试性(modifiability or testability)。
质量属性之间的关系:1. 质量属性永不可能被孤立(isolation)地实现 2. 质量属性之间相互影响,这种影响可以是正面的也可以是负面的。3.设计就是在这其中权衡( trade off)。
如何表达质量属性
质量属性要求应该是明确(无歧义)且可测试的(be unambiguous and testable)
使用通用形式指定所有质量属性要求。这是一个质量属性场景(quality attribute scenario)
质量属性场景有六部分:
- 刺激源Source of stimulus 刺激源是产生刺激的某个实体。该实体包括人、计算机系统或任何其他执行器。刺激源可能会影响系统处理它的方式,例如:可信或不可信用户的请求
- 刺激(输入)Stimulus (input) 刺激是一种在到达系统时需要响应的条件。刺激对于性能社区来说可以是事件,对于可用性社区来说可以是用户操作,或者对于安全社区来说是攻击。
- 响应(输出)Response (output) 响应是由于刺激到来而采取的活动。响应包括系统或开发人员响应刺激应履行的职责
- 响应度量 Response measure 响应度量是某种方式的度量,以便可以测试质量要求(比如响应时间,并发度)
- 环境 Environment 环境是刺激发生时的一定条件,比如系统处于什么状态下运行
- 产物(系统)Artifact (system) 产物是需求中指定的部分,可以是系统,也可以是系统的一部分
General quality attributes scenarios are system independent一般质量属性场景与系统无关
Specific quality attribute scenarios are specific to the particular system特定的质量属性场景特定于特定系统
一般质量属性场景通过实例化(选择)成为特定(具体)质量属性场景。
通过策略(Tactics)实现质量属性
定义:一个策略(Tactics)是影响质量属性响应实现的设计决策(design decision)。
策略直接影响系统对某些刺激的反应。
策略是针对单一质量属性响应
在策略内不考虑权衡,权衡必须由设计者明确考虑和控制
架构模式可以通过一组策略来构建,权衡已内置于模式中(也就是说架构模式=多种策略的权衡形成的范式)
为什么只考虑策略:1.设计模式很复杂。实际上,通常会通过更改策略以更改模式来适应需要。2. 如果不存在实现设计目标的模式,则首先选择策略 3.在某些限制下使设计更加系统化(systematic)的方法
策略应该根据实际情况细化(refined)为具体(specific)的策略
有哪些设计决策(策略):
-
职责分配Allocation of responsibilities:责任分配决定:确定重要职责,包括基本系统功能、架构基础设施和质量属性满意度;确定如何将这些职责分配给非运行时和运行时元素。做出这些决定的策略包括:1.功能分解 2.模拟现实世界的物体 3.根据系统运行的主要模式进行分组 4. 根据相似的质量要求进行分组
-
协调模型Coordination model:设计的机制相互交互,这些机制统称为协调模型。识别系统中必须协调或禁止协调的元素;确定协调的属性,如及时性、一致性、完整性、正确性;实现这些属性的通信机制(communication mechanisms)其属性包括{有状态与无状态;同步与异步;保证交付与非保证交付;与性能相关的属性,例如吞吐量和延迟 Stateful versus stateless;Synchronous versus Asynchronous;Guaranteed versus nonguaranteed delivery;Performance-related properties such as throughput and latency}
-
数据模型Data model:每个系统都必须有一些结构以某种内部方式表示系统范围内的相关数据;这些表示的集合以及如何解释它们被称为数据模型。关于数据模型的决策:1.选择主要的数据抽象(major data abstractions)、它们的操作(operations)和它们的属性( properties) 2.一致解释数据所需的令人信服的元数据 3.整理数据。这包括确定数据是否将保存在关系数据库(对象的集合)中
-
资源管理Management of Resources:架构师可能需要仲裁架构中共享资源的使用 1.硬资源:CPU、内存、电池、硬件缓冲区、系统时钟、I/O 端口 2.软资源:系统锁、软件缓冲区、线程池、非线程安全代码等。资源管理的决策:
- 识别必须管理的资源并确定限制
- 确定哪些系统元素管理每个资源
- 确定资源如何共享以及发生抢占(contention)时采用的仲裁策略
- 确定饱和度(saturation)对不同资源的影响
-
结构元素之间的映射Mapping among Architectural elements:一个 架构必须提供两种类型的映射:不同类型架构结构中元素之间的映射;元素和环境元素之间的映射
有用的映射
- 运行时元素的映射
- 将运行时元素分配给处理器(部署)processors (Deployment)
- 将数据模型中的项目分配给数据存储data stores
- 模块和运行时元素到交付单元units of delivery的映射
-
绑定时间决策Binding time decisions:绑定时间决策引入了允许的变化范围;绑定时间决策确定了范围、生命周期中的点以及实现变化的机制;其他六个类别中的决策具有关联的绑定时间决策
- 对于职责分配,通过参数化(parameterized)的makefile 进行构建时选择
- 对于协调模型的选择,设计协议的运行时协商
- 对于资源管理,设计一个系统以在运行时接受新的外围设备
-
技术选择Choice of technology:特定技术来实现。所选择的技术可能会限制七个类别中每个类别的决策。架构师应该选择合适的技术来实现决策。
决策内容:
- 为每个类别选择技术
- 选择支持技术的工具
- 提供技术文档支持外部使用
- 确定技术的副作用side effects
- 确定新技术是否与现有技术堆栈兼容compatible with
可用性(Availability)
定义:是系统屏蔽或修复故障,以使累积服务中断期在指定时间内不超过要求值的能力。
辨析:可靠性(Dependability)是指避免比可接受的情况(风险)更频繁、更严重的故障的能力。可用性在可靠性概念的基础上添加了恢复概念(notion of recovery),即当系统出现故障时,它会自行修复。可用性=可靠性+恢复
**可用性与故障:**可用性是指通过减少故障来最大限度地减少服务中断时间。故障可以预防、容忍、消除或预测。故障和故障之间的区别允许讨论自动修复策略
可用性可以计算为概率(99.999%为高可用)
可用性= MTBF / ( MTBF + MTTR )
MTBF是平均故障间隔时间
MTTR是平均修复时间
系统或托管服务提供的可用性通常表示为服务级别协议service-level agreement (SLA)
SLA 指定了保证的可用性级别,如果违反 SLA,将会受到处罚
可用性等级 | 系统类型 | 不可用 (分钟/年) | 可用性 |
---|---|---|---|
1 | 非托管 | 50,000 | 90% |
2 | 管理 | 5,000 | 99% |
3 | 管理得很好 | 500 | 99.9% |
4 | 容错 | 50 | 99.99% |
5 | 高可用性 | 5 | 99.999% |
6 | 极高可用性 | 0.5 | 99.9999% |
7 | 超高可用性 | 0.05 | 99.99999% |
故障分析树Fault tree analysis 故障树分析是一种分析技术,指定对安全性或可靠性产生负面影响的系统状态,然后分析系统的上下文和操作以找出可能发生不良状态的所有方式。该技术使用图形结构。故障树不仅可以进行静态分析,还可以进行动态分析(马尔可夫分析)。故障模式、影响和严重性分析 (FMECA) 对故障类型进行分类。FMECA 依赖于过去类似系统的故障历史。
可用性的质量属性场景
部分场景 | 可能的价值 |
---|---|
来源 | 系统内部;系统外部 |
刺激 | 故障:遗漏、崩溃、时序和响应不正确 Fault: omission, crash, incorrect timing and response |
产物 | 系统的处理器、通信通道、持久存储、进程 |
环境 | 普通手术;降级模式 |
响应 | 系统应检测事件并执行以下一项或多项操作:把它记录下来;通知有关各方;禁用事件源,继续在正常或降级模式下运行 |
响应度量 | 系统必须可用的时间间隔;可用时间;系统处于降级模式的时间间隔;修复时间 |
可用性策略Availability tactics
定义
可用性策略旨在使系统能够承受系统故障,以便系统提供的服务保持符合其规范
可用性策略将防止故障变成故障,或者至少限制故障的影响并使修复成为可能
分类
-
故障检测Fault Detect——健康监测以检测故障
策略:
- Ping/回声 Ping/echo 节点之间交换的异步请求/响应消息对。用于确定通过关联网络路径的可达性和往返延迟
- 监视器 Monitor 监视器是一个组件,用于监视系统其他各个部分的健康状态:处理器、进程、I/O、内存等
- 心跳 Heartbeat 一种故障检测机制,在系统监视器和被监视进程之间采用周期性消息交换。战术采取被动模式passive mode,类似于听取汇报。
- 时间戳 Time stamp
- 健全性检查 Sanity checking 健全性检查检查组件特定操作或输出的有效性或合理性。这种策略通常基于对内部设计的了解。
- 状态监视器 Condition monitor
- 自我测试 Self-test
- 投票(复制、功能冗余、分析冗余)Voting 基于冗余的投票。这种策略最常见的实现称为三重模块化冗余( TMR )。面对不一致的情况,投票者报告错误并决定使用什么输出,例如多数规则或平均值
- 异常检测(系统异常、参数围栏、参数输入、超时)Exception detection 异常检测是指检测改变正常执行流程的系统状况
-
故障恢复Fault Recovery——检测到故障时进行恢复
故障恢复包括恢复准备和系统修复
恢复准备Preparing for recovery 包括主动冗余、被动冗余、备用和异常处理等。
重新引入Reintroduction 包括Shadow、状态重新同步、升级重启和不间断转发(NSF)等。
**主动冗余 Active redundancy:**所有冗余组件并行响应事件它们都处于相同的状态,使用这种策略通常是毫秒,因为备份是当前的,唯一恢复的时间是切换时间
**被动冗余Passive redundancy:**一个组件(主组件)响应事件并通知其他组件(备用组件)它们必须进行的状态更新这种方法也用在控制系统中,在这种情况下,停机时间通常可以限制在几秒钟内
**备用Spare:**发生故障时,备用备用必须重新启动到适当的软件配置并初始化其状态。这种策略的停机时间通常是几分钟
检查点/回滚Checkpoint/rollback: 检查点是定期创建或响应特定事件而创建的一致状态的记录使用一致状态的先前检查点来恢复系统
异常处理Exception Handling: 一旦检测到异常,系统必须以某种方式处理它。返回错误代码。异常类包含有助于故障关联的信息,例如异常的名称、来源和原因
状态重新同步State resynchronization: 被动和主动冗余策略要求正在恢复的组件在返回服务之前升级其状态
软件升级Software upgrade: 其目标是以不影响服务的方式实现可执行代码映像的服务中升级实现方法有3种:功能补丁(bug修复)类补丁(错误修复)无中断运行(新特性和功能)
-
故障预防Fault Prevention——防止故障变成故障
该系统可以在第一时间防止故障发生。战术分为五类:停止服务,交易,预测模型,异常预防,增加能力集
停止服务Removal from service:从服务中删除:此策略将系统的某个组件从运行中删除,以进行一些活动以防止预期的故障一个例子是重新启动组件以防止内存泄漏导致故障
事务Transactions:事务语义确保分布式组件之间交换的异步消息具有原子性、一致性、隔离性和持久性(ACID) 属性。事务策略最常见的实现是两阶段提交协议此策略可防止因两次处理尝试更新同一数据项而导致的竞争条件。
**预测模型Predictive model:**预测模型监视系统过程的健康状态,以确保系统在其标称运行参数内运行。1.会话建立率 2.维护进程的统计信息(服务中、停止服务、空闲等)3.消息队列长度统计(它用于预测故障的发生)
异常预防Exception prevention:是指为防止系统异常发生而采用的技术使用包装器来防止故障
使用策略(Tactics)实现可用性设计
-
职责分配:
它确保分配额外的职责来检测遗漏、崩溃、不正确的时机或不正确的响应
- 记录故障
- 通知Notify适当的实体
- 禁用导致故障的事件源
- 暂时无法使用unavailable
- 修复或掩盖故障/故障
- 降级模式degrade mode运行
-
协调模型coordination mechanisms
确保协调机制能够检测到遗漏、崩溃、不正确的时机和响应
确保协调机制能够记录故障、通知notification 等
确保协调模型支持所用工件的替换
确定协调在通信质量下降的情况下是否有效
-
数据模型
确定哪些数据抽象及其操作或属性可能导致故障
例如,确保在服务器暂时不可用时缓存写入请求,并在服务器恢复服务时执行写入请求
-
结构元素之间的映射
确定哪些工件可能会产生故障
确保架构元素的映射足够灵活以允许从故障中恢复,包括:
- 故障处理器上的哪些进程需要在运行时重新分配
- 哪些处理器、数据存储可以在运行时激活或重新分配
- 如何将运行时元素分配给处理器
-
资源管理
确定出现故障时继续运行所需的关键资源critical resources
确定关键资源的可用时间
例如,确保输入队列足够大,以便在服务器发生故障时缓冲预期的消息
-
绑定时间
确定如何以及何时绑定架构元素。
例如:后期绑定用于在工件之间切换
后期绑定用于更改错误的定义或容忍度
后期绑定机制本身的可用性特点是什么?会失败吗?
-
技术选择
确定可检测故障、从故障中恢复或重新引入故障组件的可用技术
确定所选技术本身的可用性特征:可以从哪些故障中恢复?他们可能会给系统带来什么故障
可修改性(Modifiability)
可修改性是关于改变的,它集中于改变的成本和风险the cost and risk
变更发生的位置如下:实现(源代码);编译(编译时开关);构建(通过选择库);配置设置(参数设置);执行(参数设置、插件);开发人员、最终用户、系统管理员进行
两种成本:1.引入机制使系统更具可修改性的成本 2.使用该机制进行修改的成本
对于N个相似的修改,比较变更成本的公式如下N ×成本 1 ≤成本 2 + ( N × 成本 3 )Cost1 :没有机制的情况下进行更改的成本Cost2 :建立机制的成本Cost3 :使用该机制进行更改的成本
可修改性的质量属性场景
部分场景 | 可能的价值 |
---|---|
来源 | 最终用户、开发人员、系统管理员 |
刺激 | 添加/删除/修改功能或更改质量、容量或技术的指令 |
人工制品 | 代码、数据、接口、组件、资源、配置 |
环境 | 运行时、编译时、构建时、启动时、设计时 |
回复 | 进行修改、测试修改、部署修改 |
反应措施 | 成本如下:受影响文物的数量、大小和复杂性努力、日历时间、金钱影响其他功能或品质的程度引入新缺陷 |
刺激:
功能(添加/修改/删除)Function ( add/modify/delete
质量(可用性、可用性)Qualities ( availability, usability )
容量(支持用户数))Capacity ( users number was supported)
技术(将系统移植到不同类型的计算机或通信网络)Technology ( porting the system to a different type of computer or communication network )
可修改性策略Tactics
策略的目标是控制更改的复杂性以及更改的时间和成本
两个相关因素:内聚性Cohesion:衡量一个模块的职责相关性有多强(内聚性越高越好);耦合度Coupling:衡量一个模块的修改传播到另一个模块的概率(耦合度越低越好)
可修改性策略Tactics包括四类:
-
减小模块的尺寸Reduce size of a module
原因:如果被修改的模块包含大量的功能,那么修改成本可能会很高。解决方案:将模块细化为几个较小的模块应该可以降低未来更改的平均成本。
-
增加内聚性Increase cohesion
原因:如果模块中的职责A和B不具有相同的目的,则应将它们放置在不同的模块中。解决方案:确定要移动的职责是假设影响模块的可能变化
-
减少耦合度Reduce coupling
有五种策略策略:封装,使用中介,限制依赖关系,重构,抽象公共服务
- **封装(Encapsulate)**为模块引入了显式接口。封装降低了一个模块的更改传播propagates到其他模块的可能性。接口限制了外部职责与模块交互的方式
- 使用中介(Use an intermediary) 打破依赖例如发布-订阅中介将消除数据生产者对其消费者的了解。在面向服务的体系结构中,服务通过动态查找来发现彼此,目录服务作为中介
- 限制依赖(Restrict dependencies):该策略限制给定模块与之交互或依赖的模块。在实践中,这种策略是通过限制模块的可见性和授权来实现的。例如,分层架构,其中一个层只允许使用较低层
- **重构(Refactor)**是当两个模块由于彼此重复而受到相同更改影响时采取的策略。通过共同承担共同职责,使它们成为同一父模块的子模块
- **抽象公共服务(Abstract Common Services)**通用的形式仅实现一次服务可能会更具成本效益引入抽象的常见方法是参数化模块活动的描述。 void分析(类型、参数)
-
推迟绑定时间Defer binding time
如果我们设计具有内置灵活性的工件,那么行使这种灵活性通常比手动编码特定更改要便宜。参数Parameters可能是引入灵活性的最著名机制,绑定时间是一个参数
一般来说,在生命周期的后期我们可以绑定值,修改得越好。然而,建立机制来促进后期绑定往往成本更高。这是一个权衡
- 编译时compile time绑定值。部件更换,编译时参数化,方面
- 在部署deployment time时绑定值 配置时间绑定
- 启动或初始化startup or initialization时绑定值 资源文件
- 运行时绑定值 运行时注册,动态查找,解释参数,名称服务器,插件,发布-订阅,共享存储库,多态性
使用策略实现可修改性设计
-
职责分配
技术、法律、社会、业务和客户方面可能发生哪些变化
- 确定为进行更改而添加、修改或删除的职责
- 确定哪些职责受到变更的影响
- 确定将在同一模块中一起更改的模块的职责分配
-
协调模型
在运行时更改以及这如何影响协调。确定哪些用于协调的设备、协议和通信路径可能会发生变化。减少耦合的协调模型,例如 SOA 结构延迟绑定
-
数据模型
数据抽象、其操作或其属性可能发生哪些更改。数据抽象变化包括数据创建、初始化、持久化、操作、转换或销毁。
确定需要添加、修改哪些数据以进行更改。这些数据的创建、持久化或销毁是否会发生任何变化。确定哪些其他数据受到更改的影响。确保数据分配最大限度地减少变更造成的修改数量和严重程度(多通道采样)
-
结构元素之间的映射
在运行时、编译时、设计时或构建时将功能映射到计算元素的方式。确定适应功能或质量属性的添加、删除或修改所需的修改程度。
-
资源管理
确定责任或质量属性的添加、删除或修改将如何影响资源使用:新建、删除或限制资源。确保修改后资源充足。封装所有资源管理器并确保尽可能推迟绑定。
-
绑定时间
对于每个变更或变更类别:
- 确定最近更改时间
- 选择延迟绑定机制
- 确定引入机制的成本以及使用所选机制进行更改的成本
- 不要引入过多的绑定选择,因为选择之间的依赖关系复杂且未知,因此会阻碍更改
-
技术选择
确定您的技术选择使哪些修改变得更容易或更困难
技术选择是否有助于进行、测试和部署修改
修改您选择的技术有多容易(HTML5跨平台)
性能(Performance)
什么是性能:性能与时间以及软件系统满足时序要求的能力有关。性能与事件到达和对事件的响应有关。事件属性以及系统或元素对这些事件的基于时间的响应是性能的本质。
在软件工程的历史上,性能一直是系统架构的驱动因素
性能的质量属性场景
部分场景 | 可能的价值 |
---|---|
来源 | 系统内部或外部 |
刺激 | 周期性、偶发性或随机事件的到来 |
产品 | 系统或系统中的一个或多个组件 |
环境 | 运行模式:正常、紧急、高峰、超载 |
响应 | 处理事件,更改服务级别 |
响应度量 | 延迟、截止时间、吞吐量、抖动、错过率 Latency, deadline, throughput, jitter, miss rate |
响应度量:延迟:刺激到来到系统做出响应之间的时间。处理中的截止日期:必须处理事件之前的阈值时间。吞吐量:系统单位时间内可以处理的交易数量。抖动:延迟的允许变化。未命中率:由于系统太忙而无法响应而未处理的事件数量
性能策略
目标是在某个基于时间的约束内生成对到达系统的事件的响应
响应时间的两个基本因素:
处理时间Processing time:系统正在工作响应;
阻塞时间Blocked time:系统无法响应。阻塞时间类型:
- 资源竞争:多个流竞争同一资源
- 资源可用性:资源不可用
- 对其他计算的依赖性:计算可能必须等待,因为它必须与另一个计算的结果同步
两类性能策略
-
控制资源需求Control resource demand:这种策略在需求方运作以产生较小的
控制资源需求的策略有两类:1.处理的事件数量 2.系统响应事件的速率
具体策略:
- 管理采样率:可以降低采样频率,可以降低需求这种策略通常会伴随一些保真度损失(副作用)
- 限制事件响应:当离散事件到达系统太快而无法处理时,则必须对事件进行排队直到可以处理它们。该策略不可接受丢失任何事件,系统仅以设定的最大速率处理事件。
- 对事件进行优先级排序:如果不是所有事件都同等重要,您可以强加一个对事件进行排名的优先级方案。如果没有足够的可用资源,低优先级事件可能会被忽略。
- 减少开销:中介的使用会增加资源消耗,删除中介会改善延迟。这是可修改性/性能的权衡减少计算开销的策略是共同定位资源。共同定位资源包括以下内容:1.将协同组件托管在同一处理器上,避免网络通信的时间延迟 2.将资源放在同一个运行时软件组件中以避免子例程调用的开销3.清理效率低下的资源
- 绑定执行时间:对用于响应事件的执行时间进行限制。对于迭代来说,限制迭代次数是限制执行时间的一种方法。绑定执行时间通常是不太准确的计算。
- 提高资源效率:改进关键领域使用的算法将减少延迟。例如: 使用二分搜索算法比其他搜索算法更高效
-
管理资源Mange resources:此策略在响应方运行,使手头的资源更有效地处理需求。
管理资源策略通常应用于处理器,但应用于磁盘等其他资源时也很有效,有时一种资源可以交换另一种资源。例如,中间数据可以保存在缓存中,也可以根据时间和空间资源的可用性重新生成
具体策略:
-
增加资源:更快的处理器、额外的处理器、额外的内存和更快的网络都有可能减少延迟。增加资源是有一定成本的。然而,在许多情况下,这是立即改善的最便宜的方法。
-
引入并发:如果可以并行处理请求,则可以减少阻塞时间。可以通过在不同线程上处理不同的事件流或创建额外的线程来处理不同的活动来引入并发性。
由于存在称为竞争条件的交错现象,并发性必须由架构师进行管理。当有两个控制线程并且存在共享状态时,可能会出现竞争条件。
有两种技术可以防止竞态条件:1.使用锁强制顺序访问状态 2. 根据执行部分代码的线程对状态进行分区。即x有两个实例,x不被这两个实例共享
-
维护计算的多个副本:客户端-服务器模式中的多个服务器是计算的副本副本的目的是减少如果所有计算都在单个服务器上进行时可能发生的争用需要负载均衡器将新工作分配给其中一台可用服务器
维护数据的多个副本:缓存是一种策略,涉及以不同的访问速度将数据副本保留在存储上。数据复制涉及保留数据的单独副本,以减少多个同时访问的争用
-
绑定队列大小:此策略控制排队到达的最大数量以及用于处理到达的资源。队列溢出时发生的情况采取策略,并决定是否可以接受不响应丢失的事件。
-
调度资源: 每当存在资源争用时,就必须调度该资源。您需要了解每种资源的特点;使用并选择与其兼容的调度策略
-
调度策略 略
使用策略实现性能设计
-
职责分配
重负载、具有时间关键响应要求的系统职责。有三种:
- 跨进程或处理器边界的控制线程产生的责任
- 控制线程的职责
- 调度共享资源或管理资源的职责
-
协调模型
相互协调的元素。有一些机制:
- 支持任意引入并发
- 可以根据需要捕获周期性、随机或零星事件的到达
- 通信机制属性
-
数据模型
确定数据模型中负载较重的部分。确定以下内容:
- 是否维护数据的多份副本
- 数据分区是否有利于性能
- 数据抽象的处理要求
-
结构元素之间的映射
确定是否共置某些组件。确定在哪里引入并发。确定控制线程及其相关职责的选择是否会引入瓶颈。确保计算量大的组件分配给处理能力最强的处理器。
-
资源管理
确定系统中哪些资源对性能至关重要。如下:
- 需要了解并管理时间和其他性能关键资源的系统元素
- 进程/线程模型
- 优先级和资源的访问
- 调度和锁定策略
- 是否添加资源以减少瓶颈
-
绑定时间
对于编译后将绑定的每个元素,确定以下内容:
- 完成绑定所需时间
- 使用后期绑定机制引入的额外开销
- 确保这些值不会对系统造成不可接受的性能损失
-
技术选择
技术选择如下:1. 调度策略 2. 优先事项 3.减少需求的政策 4.将部分技术分配给处理器 5.其他性能相关参数
易用性(Usability)
易用性涉及用户完成所需任务的容易程度以及系统提供的用户支持类型
易用性是提高系统质量最便宜、最简单的方法。
易用性包括
- 学习系统特点
- 有效地使用系统
- 最大限度地减少错误的影响
- 使系统适应用户需求
- 增加用户的信心和满意度
易用性的质量属性场景
部分场景 | 可能的价值 |
---|---|
来源 | 最终用户,可能担任特殊角色 |
刺激 | 最终用户尝试有效地使用系统,学习使用系统,最小化错误的影响,适应系统 |
人工制品 | 系统或系统中与用户交互的特定部分 |
环境 | 运行时或配置时 |
回复 | 系统应该为用户提供所需的功能 |
反应措施 | 任务时间、错误数量、完成的任务数量、用户满意度、用户知识获取、成功操作与总操作的比率 |
易用性策略
策略的目标是让用户完成所需的任务
分离用户界面
架构师使系统可用于通过原型(prototypes)促进用户界面(the user interface)的实验
构建多个原型,让真实用户体验界面experience the interface)并提供反馈feedback
做到这一点的最佳方法是设计软件,以便可以快速更改用户界面
如何分离用户界面 1. 增加语义一致性semantic coherence、封装encapsulate和共置co-locate相关职责,从而本地化用户界面职责。 2.限制依赖性Restrict dependencies,这可以最大限度地减少用户界面更改时对其他软件的连锁反应。3.延迟绑定Defer binding,使您可以做出关键的用户界面选择
MVC模式是主要的用户界面分离模式。
两类易用性策略
- 支持用户倡议:用户主动提出请求,系统反馈处理。一旦系统正在执行,通过向用户提供有关系统正在做什么的反馈并允许用户做出适当的响应,可用性就会得到增强。
- 取消Cancel:当用户发出取消命令时,系统必须监听。取消包括:1. 被取消的命令必须终止 2.必须释放已取消命令正在使用的任何资源 3.必须通知与取消的命令协作的组件
- 撤销Undo:为了支持撤消功能,系统必须维护足够数量的系统状态信息,以便可以恢复较早的状态。并非所有操作都可以轻松逆转
- 暂停/恢复Pause/resume:当用户发起长时间运行的操作时,提供暂停和恢复操作的能力通常很有用。有效地暂停长时间运行的操作需要能够暂时释放资源,以便将它们重新分配给其他任务
- 聚合Aggregate:当用户执行重复操作,或者以相同方式影响大量对象的操作时,提供将较低级别的对象聚合到单个组中的功能非常有用,以便可以应用该操作到小组。
- 支持系统倡议:系统维护用户模型,主动响应用户请求。支持系统主动策略是识别系统用于预测其自身行为或用户意图的模型的策略。
- 维护任务模型 Maintain Task Model 任务模型用于**确定上下文context **,以便系统可以了解用户正在尝试什么并提供帮助。
- 维护用户模型Maintain User Model 该模型明确表示用户对系统的了解、用户在预期响应时间方面的行为以及特定于用户或用户类别的其他方面
- 维护系统模型Maintain System Model 系统维护一个明确的自身模型,用于确定预期的系统行为,以便向用户提供适当的反馈。
使用策略实现易用性设计
-
职责分配
确保已分配额外的系统职责
- 学习如何使用系统
- 高效完成手头的任务
- 调整和配置系统
- 从用户和系统错误中恢复
-
协调模型
确定系统要素协调的属性,如何影响
- 用户学习使用系统
- 实现目标或完成任务
- 调整和配置系统
- 从用户和系统错误中恢复并增强信心和满意度
-
数据模型
确定与用户可感知行为相关的主要数据抽象
确保这些主要数据抽象的设计能够满足用户的操作
例如,维护undo命令的旧状态数据,维护用户模型等。
-
结构元素之间的映射
最终用户可以看到架构元素之间的哪些映射。例如,最终用户了解哪些服务是本地的、哪些是远程的的程度
-
资源管理
确定用户如何适应和配置系统对资源的使用。确保所有用户控制的配置下的资源限制不会降低用户完成任务的可能性。确保资源水平不会影响用户的操作能力。
-
绑定时间
确定哪些绑定时间决策应由用户控制。
确保用户可以做出有助于可用性的决策
例如,如果用户可以在运行时选择系统的配置或其通信协议或其通过插件的功能,则需要确保该选择不会影响用户。
-
技术选择
确保所选技术有助于实现适用于您的系统的可用性场景
例如,这些技术是否有助于创建在线帮助、制作培训材料以及收集用户反馈
可变性(Variability)可修改性的特殊形式
**定义:**系统及其支持工件(例如需求、测试计划和配置规范)支持以预先计划的方式生产一组彼此不同的变体的能力。
作用:可变性用于软件产品线。产品线是指核心资产适应产品线范围内不同产品环境中使用的能力
**来源:**角色要求可变性
刺激:
- 请求支持以下方面的变化:硬件、功能集、技术、用户界面、质量属性等
- 对于受影响的产品范围,例如:全部、指定子集、包含功能集 x 和新产品的产品
**环境:**变体将在以下时间创建:运行时、构建时、开发时
产品:受影响的资产,例如: 需求、架构、组件、测试套件 y、项目计划 z 等
响应:可以创建所请求的变体
**响应度量:**创建核心资产并使用这些核心资产创建变体的指定成本和/或时间。
可移植性(Portability)可修改性的特殊形式
**定义:**可以更改为在不同平台上运行的难易程度。
**实现:**可移植性是通过最小化软件中的平台依赖性、将依赖性隔离到明确识别的位置以及编写在“虚拟机”上运行的软件来实现的。虚拟机如 JVM或HTML5语言
开发可分发性(Development Distributability)
**定义:**开发可分配性是支持分布式软件开发的软件设计质量。
如今许多系统都是使用分布在全球的团队开发的
**实现:**分布式开发必须克服协调问题。系统的设计应尽量减少团队之间的协调。代码和数据模型都需要实现最小的协调。
可拓展性(Scalability)可修改性的特殊形式
**定义:**两种可扩展性:
- 水平可扩展性Horizontal scalability是指向逻辑单元添加更多资源c
- 垂直拓展性Vertical scalability是指向物理单位添加更多资源
**实现:**可扩展性必须解决如何有效利用额外的资源。有效意味着额外的资源可以显着提高系统质量,不需要额外的努力来添加,并且不会中断运营。
在云环境中,水平可扩展性称为弹性elasticity。弹性是一种属性,使客户能够在资源池中添加或删除虚拟机这些虚拟机托管在由云提供商管理的超过 10,000 台物理机的大型集合上
可部署性(Deployability)
定义:可部署性 关注可执行文件如何到达arrives主机平台以及随后如何调用 invoked
部署场景将处理更新类型(推送或拉取)、更新形式(介质,例如 DVD 或互联网下载)
可移动性(Mobility)
移动性问题包括:电池管理;一段时间后重新连接;支持多个平台所需的不同用户界面的数量。
可监控性(Monitorability)
**定义:**可监控性 涉及操作人员在系统执行时监控系统的能力
监控软件内部状态,例如队列长度、平均事务处理时间以及各个组件的运行状况
安全性(Safety)可用性的特殊形式
**定义:**软件安全是指软件避免进入对参与者造成损害、伤害或生命损失的状态的能力
安全涉及危险故障的预防和恢复
安全策略与可用性策略重叠
其它质量属性
构架概念完整性(Conceptual integrity of the architecture)
定义:是指架构设计的一致性,它有助于架构的可理解性并减少混乱的错误
概念完整性要求通过架构以相同的方式完成相同的事情。在具有概念完整性的架构中,少即是多例如,组件可以通过无数种方式相互发送信息:消息、数据结构、事件信号等等。然而,仅使用一种方法。以相同的方式报告和处理错误。
使用质量(Quality in Use)
使用中的一些品质如下:
- 有效性:正确构建系统(需求)和构建正确的系统(用户愿望)
- 效率:开发系统所需的精力和时间
- 免于风险:产品或系统影响经济状况、人类生命、健康等的程度。
适销性(Marketablity)
有些系统因其架构而广为人知,而这些架构有时具有其自身的含义
当前构建基于云的系统的热潮告诉我们,架构的感知可能比架构带来的品质更重要
质量属性标准清单
- 功能适用性(功能完整性、正确性和适当性)Functional suitability (Functional completeness, Correctness and Appropriateness)
- 性能效率(时间行为、资源利用率和容量)Performance efficiency (Time behavior, Resource utilization and capacity)
- 兼容性(共存互操作性)Compatibility ( Coexistence Interoperability)
- 易用性(适当性可识别性、可学习性、可操作性、用户错误预测、用户界面美观性、可访问性)Usability ( Appropriateness recognizability, Learnability, Operability, User error prediction, User interface aesthetics, Accessibility)
- 可靠性(成熟度、可用性、容错性、可恢复性)Reliability (Maturity, Availability, Fault tolerance, Recoverability)
- 便携性(适应性、可安装性、可替换性)Portability (Adaptability, Installability, Replaceability)
- 安全性(保密性、完整性、不可否认性、责任性、真实性)Security (Confidentiality, Integrity, Nonrepudiation, Accountability, Authenticity)
- 可维护性(模块化、可重用性、可分析性、可修改性、可测试性)Maintainability (Modularity, Reusability, Analyzability, Modifiability, Testability)
如何应对新的质量属性
-
捕获新质量属性的场景
通过采访利益相关者来构建一组属性特征来捕捉场景。一旦有了一组特定场景,您就可以对集合进行概括。查看一组刺激、反应等。
-
新质量属性的设计方法
组装设计方法是:
- 重新审视设计模式的主体
- 搜索处理此 QA 的设计
- 寻找该领域的专家并采访他们
- 使用一般场景尝试对设计方法列表进行编目
- 无法响应的方式列表
-
新的质量属性建模
如果您可以构建质量属性的概念模型,这将有助于为其创建一组设计方法。
通过模型,我们的意思只是理解质量属性对其敏感的参数集。
-
为新的质量属性制定一套策略
有两个来源可以用来导出针对任何质量属性的策略:
- Model :枚举模型的参数,对于每个参数,枚举架构决策(策略)
- 专家:采访该领域的专家然后总结
-
为新的质量属性构建设计清单
最后,检查设计决策的七个类别,并问自己如何将您感兴趣的新质量专门化到这些类别
审查软件架构并尝试找出它在这七个类别中满足您的新品质的程度
构架模式
**定义:**架构模式:
- 是在实践中反复发现的一揽子设计决策
- 具有允许重复使用的已知属性
- 描述一类架构
何为架构模式
架构模式是一种通用的架构
在架构模式中,元素的组合方式可以解决 特殊问题
架构模式提供了解决系统面临的一些问题的打包策略
背景是世界上反复出现的、常见的情况,它会引起问题。
架构模式提供的解决方案包括:
- 解决问题的结构structures
- 元素之间的职责和静态关系static relationships
- 运行时行为和交互interaction
即:模式{名字、上下文环境、问题、解决方案}
解决方案{元素、元素间的交互关系、组件拓扑布局、包含拓扑、行为的语义约束}
复杂系统同时表现出多种模式
模式的三种分类
模块模式Module patterns(分层模式Layered Pattern)
组件和连接器模式Component-and-Connector patterns(代理、发布-订阅 Broker, Publish-Subscribe)
分配模式Allocation patterns(Map-Reduce、多层Map-Reduce, Multi-tier)
分层模式(Layered Pattern)
分层模式是一种模块模式
分层模式是所有软件工程中最常用的模式之一,但仍然会出现一些错误
首先,不可能通过查看一堆盒子来判断是否允许层桥接(不清楚)
通过添加图表的符号来解决问题
环境
所有复杂的系统都需要独立开发和发展系统的各个部分
该系统需要清晰且有据可查的关注点分离
解决的问题
软件需要进行分段,以便模块可以单独开发和发展developed and evolved separately ,而各部分之间几乎没有交互little interaction
解决方案
分层模式将软件划分为称为层的单元
每层都是一组模块,提供一组有凝聚力的服务cohesive set of service
- **元素Element:**层layer,一种模块该层提供的一组内聚服务的特征Modules contains and a characterization of the cohesive set of services that the layer provides
- **元素交互关系:**允许使用Allowed to use,这是更通用的依赖关系的特化。例如高层单向使用低层的服务
- 约束:
- 每个软件都被准确地分配到层上
- 至少有两层
- 允许使用关系不应是循环的(不能循环调用)
支持的质量属性
分层模式支持:可移植性,可修改性,重用
优缺点
缺点: 1. 添加层会增加系统的前期成本和复杂性层 2.会降低性能
层桥接(Layer bridging)
**定义:**这种较高层的软件使用不相邻的较低层中的模块的情况称为层桥接
如果发生许多层桥接的实例,系统可能无法满足严格分层有助于实现的可移植性和可修改性目标。
经纪人模式(Broker)
代理模式属于组件-连接器模式
代理模式定义了一个称为代理的运行时组件,它协调多个客户端和服务器之间的通信。
辨析
Broker(经纪人):
- 含义: Broker 是一种中介或调解者,用于协调不同组件或系统之间的通信。它负责处理和转发消息、请求或事件,以促成系统中各个部分之间的交互。
- 作用:
- 解耦性: 经纪人可以帮助实现系统的解耦,使得各个组件不直接依赖于彼此。
- 消息传递: 经纪人通常用于支持消息传递模式,其中组件通过向经纪人发送消息来进行通信,而不是直接调用彼此的方法或接口。
- 事件处理: 经纪人也常用于事件驱动系统,它可以接收和分发事件,以触发相应的处理逻辑。
- 相似和区别:
- 相似点: 与代理一样,经纪人也有中介的角色,负责协调和管理不同组件之间的交互。
- 区别: 经纪人更强调在组件之间传递消息和协调事件,而代理通常更关注在访问控制和隐藏真实实现的情况下提供相同的接口。
Proxy(代理):
- 含义: 代理是一种结构模式,它充当另一个对象的接口或占位符,以控制对这个对象的访问。代理通常在访问真实对象之前或之后执行一些额外的操作,例如身份验证、缓存、延迟加载等。
- 作用:
- 访问控制: 代理可以控制对真实对象的访问,实现权限控制、安全性等。
- 性能优化: 代理可以实现缓存或延迟加载,以优化系统性能。
- 实现透明性: 客户端可能不需要知道它正在与真实对象交互,代理可以提供透明的访问。
- 相似和区别:
- 相似点: 与经纪人一样,代理也具有中介的特性,用于控制和管理访问。
- 区别: 代理更侧重于对单个对象的访问控制和增强,而经纪人更倾向于协调多个组件之间的通信。
环境
服务集合构建的分布在多个服务器上
实施这些系统很复杂,因为您需要担心:
- 系统如何互操作
- 他们将如何相互联系
- 他们将如何交换信息
- 服务的可用性
解决的问题
我们如何构建分布式软件,以便服务用户不需要知道服务提供商的性质和位置。我们如何轻松地动态更改用户和提供者之间的绑定?
解决方案
代理模式通过插入称为代理broker的中介inserting an intermediary将客户端与服务器分开。
当客户端需要服务时,它通过服务接口查询代理
客户端仍然完全不知道ignorant服务器的身份、位置和特征identity, location, and characteristics。
- 元素:
- 客户,服务的请求者
- 服务器,服务的提供者
- 经纪人、中介人
- 客户端代理,管理与代理实际通信的中介(proxy)
- 服务器端代理(proxy)
- 元素交互关系:附着关系attachment relation将客户端和服务器与代理关联起来
- 约束:客户端只能连接到经纪人broker(可能通过客户端proxies);服务器只能连接到经纪人broker (可能通过服务器端proxies)
优缺点
优点:
- 可修改性的好处,使用中介策略
- 可用性优势,因为代理模式很容易替换出现故障的服务器
- 性能优势,因为代理模式可以轻松地将工作分配给最不繁忙的服务器
缺点:
- 经纪人增加了前期的复杂性
- 代理可能会出现单点故障(可用性)
- 安全攻击的目标
- 经纪人可能很难测试
- 代理导致延迟,代理可能是通信瓶颈
MVC模式
模型-视图-控制器模式属于组件和连接器模式
MVC 模式将系统功能分为三个组件:模型、视图以及在模型和视图之间进行协调的控制器。
环境
用户界面软件通常是交互式应用程序中修改最频繁的部分
将对用户界面软件的修改与系统的其余部分分开
不同的角度查看数据,例如条形图或饼图
解决的问题
如何将用户界面功能与应用程序功能分开,同时仍然能够响应用户输入或底层应用程序数据的更改?
数据发生变化时,如何创建、维护和协调用户界面的多个视图?
解决方案
MVC 模式将应用程序功能分为三种组件:
包含数据的模型(model),
视图(view)显示数据的某些部分并与用户交互,
控制器(controller)在模型和视图之间进行协调并管理状态更改的通知。
-
元素
模型是应用程序数据或状态的表示
视图是一个用户界面,它要么生成模型的表示,要么允许某种形式的用户输入
控制器管理模型和视图之间的交互,将用户操作转化为变化
-
元素交互关系:通知关系连接模型、视图和控制器的实例,通知相关状态变化的元素
-
约束:模型、视图和控制器至少各有一个实例
支持的质量属性
可维护性、可拓展性、可测试性、可重用性、可伸缩性等
优缺点
**缺点:**1.对于简单的用户界面来说,它的复杂性不值得 2.模型、视图和控制器抽象可能不太适合某些用户界面工具包,一些商业用户界面工具包将输入和输出组合到单独的小部件中。
优点: 由于这些组件是松耦合的,因此很容易并行开发和测试它们,并且对其中一个组件的更改对其他组件的影响最小。
管道过滤器模式(Pipe-and-Filter Pattern)
管道和过滤器模式属于组件和连接器模式
**定义:**管道和过滤器模式通过由管道连接的过滤器执行的一系列转换,将数据从系统的外部输入转换到其外部输出。
环境
许多系统需要将数据项流从输入转换为输出
许多类型的转换在实践中重复发生,因此需要将它们创建为独立的、可重用的部分independent, reusable parts
解决的问题
此类系统需要划分为可重用reusable、松散耦合loosely coupled的组件,并具有简单、通用的交互机制
- 组件之间可以灵活组合flexibly combined
- 组件很容易重复使用reused
- 组件独立independent,可以并行执行execute in parallel
解决方案
管道和过滤器模式的特点是数据流的连续转换
数据到达过滤器输入端口,进行转换,然后通过其输出端口通过管道传递到下一个过滤器
-
元素:
- 管道:是将数据从一个过滤器的输出端口传送到另一个过滤器的输入端口的连接器connector。管道有单个源和单个目标。管道保存preserves数据。特征:缓冲区大小;交互协议;传输速度;数据格式。
- 过滤器:输入端口读取的数据转换为输出端口写入的数据的组件。过滤器可以并发执行。过滤器可以增量地转换数据。特征:处理率processing rates;输入/输出数据格式;转型transformation。
-
元素交互关系:连接关系attachment relation将过滤器的输出与管道的输入相关联,反之亦然。
-
约束
管道将过滤器输出端口连接到过滤器输入端口
连接的过滤器必须同意沿管道传递的数据类型
某些专业化可能规定组件具有某些命名端口,例如UNIX 过滤器的stdin、stdout 和 stderr 端口
优缺点
缺点:
对于交互式系统,管道和过滤器模式通常不是一个好的选择
拥有大量独立的过滤器会增加计算开销
管道和过滤器系统可能不适合长时间运行的计算
由于任何过滤器(或管道)的故障都可能导致整个管道故障
**应用:**数据转换系统,例如视频流信号处理应用UNIX 管道:Apache Web 服务器、map-reduce 模式
客户端/服务器模式(Client/Server Pattern)
客户端/服务器模式属于组件和连接器模式
环境
存在大量分布式distributed客户端希望访问的共享资源和服务shared resources and services,并且我们希望控制其访问或服务质量。
解决的问题
通过管理一组共享资源和服务,我们可以怎样做?
促进可修改性和重用
提高可扩展性和可用性
解决方案
- 元素:
- 客户端Client:服务器组件服务的组件;客户端有描述他们所需服务的端口
- 服务器Server:为客户端提供服务的组件;服务器具有描述其提供的服务的端口;重要特征包括有关服务器端口性质和性能特征的信息
- 请求/重播连接器Request/replay connector:请求/重放协议的数据连接器重要特征包括调用是本地还是远程,以及数据是否加密
- 元素交互关系:附着attachment关系将客户端与服务器关联起来
- 约束:
- 客户端通过请求/重放连接器连接到服务器
- 服务器组件可以是其他服务器的客户端
- 专业化可能会施加限制restrictions: 给定端口的附件数量;服务器之间允许的关系
- 组件可以分层tiers排列
优缺点
缺点:
- 服务器可能是性能瓶颈
- 服务器可能会出现单点故障
- 关于在何处定位功能(在客户端或在服务器中)的决定通常很复杂,并且在系统构建后更改成本高昂。
应用
客户端/服务器模式应用最广泛
- 信息系统,其中客户端是 GUI 启动的应用程序,服务器是数据库管理系统
- 基于 Web 的应用程序,其中客户端是 Web 浏览器,服务器在电子商务网站上运行
P2P模式(Peer-to-Peer Pattern)
点对点(P2P)模式属于组件和连接器模式
对等模式通过网络上的相互协作的peer 请求服务和向对方提供服务来实现计算
环境
分布式计算实体,每个实体在启动交互方面都被认为同等重要
每个实体都向分布式用户社区提供自己的服务资源
解决的问题
一组怎样才能相等 分布式计算实体通过通用协议相互连接,以便它们能够以高可用性和可扩展性组织和共享其服务?
解决方案
在 P2P 模式中,组件直接作为对等点进行交互
所有同龄人都是平等的
没有任何对等点或对等点组对于系统的健康状况至关重要
每个对等组件既是客户端又是服务器
每个对等点提供和使用类似的服务并使用相同的协议
- 元素:Peer ,是运行在网络节点上的独立组件。特殊的对等组件可以提供路由、索引和对等搜索功能
- 元素交互关系:请求/重放连接器,用于连接对等网络、搜索其他对等点以及调用服务。该关系将同级与其连接器关联起来附件可能会在运行时更改
- 约束:
- 允许数量_ _ 任何给定对等点的附件
- 用于搜索对等点的跳数哪些同行知道
- 哪些其他同行
优缺点
缺点:
- 管理安全性、数据一致性、数据/服务可用性、备份和恢复都更加复杂
- 小型 P2P 系统可能无法始终如一地实现性能和可用性等质量目标
优点:
- 可扩展性:可以添加和删除对等点,不会产生重大影响
- 可用性:多个对等点提供同等服务
- 性能:多个对等点具有重叠的功能,作为服务器的任何给定对等组件上的负载都会减少
应用
文件共享: BitTorrent和eDonkey。即时通讯:Skype。桌面网格计算。路由。无线自组织网络。
面向服务的架构模式(Service-Oriented Architecture Pattern)
面向服务的架构(SOA)模式属于组件和连接器模式
环境
许多服务由服务提供者提供,消费者由服务消费者提供
服务使用者需要能够理解和使用这些服务,而无需了解其实现的详细信息
解决的问题
我们如何支持运行在不同平台上、用不同实现语言编写、由不同组织提供并分布在互联网上的分布式组件的互操作性interoperability。
解决方案
SOA模式描述了提供和/或使用服务的分布式组件distributed components的集合
服务在很大程度上是独立的:服务提供者和服务使用者通常是独立部署的
- 元素
- 服务供应商Service providers
- 服务消费者Service consumers
- 企业服务总线(ESB)Enterprise service bus 它是一个中介,可以在服务提供者和消费者之间路由和转换消息。ESB 可以将消息从一种协议或技术转换为另一种协议或技术
- 服务登记处Registry of services
- 编排服务器Orchestration server
- 连接器Connector 有三个基本类型:1. SOAP连接器,使用 SOAP 协议在 Web 服务之间进行同步通信 2.REST(Representational State Transfer)连接器,依赖于基本的请求/重放操作 3.异步消息连接器,它使用消息系统
- 元素交互关系:将不同类型的组件连接到相应的连接器
- 约束:服务消费者连接到服务提供者,但可以使用中间组件(例如,ESB、注册表、编排服务器)
优缺点
缺点:
- 基于 SOA 的系统通常构建起来很复杂
- 您无法控制独立服务的演变
- 中间件存在性能开销,服务可能是性能瓶颈
**优点:**互操作性:由于服务提供者和服务消费者可能运行在不同的平台上,SOA经常集成多种系统
发布订阅模式(Publish-Subscribe Pattern)
发布-订阅模式属于组件和连接器模式
在发布-订阅模式中,组件发布和订阅事件
当组件宣布事件时,连接器基础结构会将事件分派给所有注册订阅者
环境
有许多独立的数据生产者和消费者必须进行交互
数据生产者和消费者的精确数量和性质并不是预先确定或固定的,他们共享的数据也不是预先确定或固定的
解决的问题
我们如何创建集成机制integration mechanisms来支持生产者和消费者之间传输消息的能力,使他们不知道unaware彼此的身份,或者潜在地了解他们的存在existence?
解决方案
在发布-订阅模式中,组件通过宣布的消息或事件进行交互
组件可以订阅一组事件
- 元素 :
- 任何具有至少一个发布或订阅端口的C&C 组件
- 发布-订阅连接器publish-subscribe connector,它将为希望发布和订阅事件的组件提供公告和侦听角色
- 元素交互关系:附件attachment关系通过规定哪些组件宣布事件以及哪些组件注册来接收事件,将组件与发布-订阅连接器关联起来
- 约束:
- 所有组件都连接到事件分发器event distributor
- 发布Publish端口具有宣布announce角色,订阅subscribe 端口具有监听listen角色
- 系统中可以存在许多发布-订阅连接器
几种形式
- 基于列表的发布-订阅List-based publish-subscribe是每个发布者维护一个订阅列表的模式的实现
- 广泛的发布-订阅Broad-based publish-subscribe简单地广播broadcast事件
- 基于内容的发布-订阅Content-based publish-subscribe 将事件分类为基于主题topic-based
优缺点
缺点:
- 增加延迟
- 对消息传递时间的可扩展性和可预测性有负面影响
- 消息顺序的控制较少
- 无法保证消息的传递
应用
图形用户界面( GUI )系统。基于MVC的应用程序。企业资源规划( ERP )系统,集成了许多部分。可扩展的编程环境。邮件列表。
映射-化简模式(Map-Reduce Pattern)
Map -Reduce 模式属于分配模式allocation pattern。
Map-Reduce 模式提供了一个框架,用于分析将在一组处理器上并行执行的大型分布式数据集
这种并行化可实现低延迟low latency和高可用性high availability
环境
企业迫切需要快速分析PB 级的海量数据,例如社交网站日志、搜索引擎的<源、目标> Web 链接对
用于分析该数据的程序应该有效地运行,并且对于硬件故障具有弹性resilient。
解决的问题
对于许多具有超大型数据集的应用来说,对数据进行排序然后分析分组的数据就足够了。
Map-Reduce模式解决的问题是高效地对大数据集进行分布式并行排序,并为程序员提供一种简单的方法来指定要进行的分析
解决方案
需要三个部分:专门的基础设施负责将软件分配到大规模并行计算环境中的硬件节点;Map;Reduce
-
元素
- Map是一个跨多个处理器部署多个实例的函数。目的是对数据集进行过滤和排序。Key1 :用于过滤数据。Key2 :用于排序。使用多个map实例来提高性能,数据集被分成几部分
- Reduce是一个可以部署为单个或多个实例的函数。Reduce进行一些程序员指定的分析,然后发出结果。输出集几乎总是比输入集小得多,因此称为“ reduce ”。
- 基础设施是负责部署map和reduce实例的框架
-
元素交互关系:
**部署于Deploy on **是映射或化简函数的实例与其安装的处理器之间的关系。
实例化、监控和控制Instantiate, monitor, and control是基础设施与Map和Reduce实例之间的关系
-
约束
- 要分析的数据必须作为一组文件存在
- 映射函数是无状态stateless的并且相互之间不通信
- Map 实例和Reduce 实例之间的唯一通信是从Map 实例以 <key, value> 对形式发出的数据
优缺点
缺点:
- 如果你不 拥有大型数据集,map-reduce 的开销是不合理的
- 如果无法将数据集划分为大小相似的子集,那么并行性的优势就会丧失。
- 需要多次归约的操作编排起来很复杂
策略与模式
模式和策略共同构成了软件架构师的主要工具。
关系是:模式包含策略;使用策略来增强模式。
模式包含策略
策略是设计的基石building blocks,从中创建架构模式
策略是原子,模式是分子
大多数模式由几种不同的策略组成,尽管这些策略可能都服务于一个共同的目的。
层模式和策略
分层模式可以看作是多种策略的混合体:
- 增加语义连贯性:通过选择具有语义一致性的职责来实现确保某一层的职责全部协同工作而不会过度依赖其他层的目标
- 抽象公共服务
- 封装;
- 限制通信路径;层定义一个顺序,只允许一个层使用其相邻下层的服务
- 中介
策略增强模式
模式被描述为一般上下文中一类问题的解决方案
当选择并应用一种模式时,其应用的上下文就变得非常具体
**具体化:**为了使模式在给定的架构环境中发挥作用,我们需要从两个角度来检查它:1. 模式所做出的内在质量属性权衡。 2.该模式不直接涉及但仍会影响的其他质量属性(副作用)
共同运用策略
策略是旨在管理单一质量属性响应的设计原语。
但在实践中,每种策略不仅有其主效,也有其副作用,这是一种权衡。
无论你做什么来提高一种品质属性都会危及另一种品质属性。
示例:
设计模式
设计模式分为三种主要类型:
-
创造型设计模式(Creational Design Pattern)、
-
结构型设计模式(Structural Design Pattern)
-
行为型设计模式(Behavioral Design Pattern)。
以下是每种类型中一些常见的设计模式:
创造型设计模式(Creational Design Pattern):
创意设计模式是解决对象创建机制的设计模式
**目的:**增加对象创建的灵活性
**方式:**创建与使用分离。思路:封装具体类的知识,隐藏创建细节
- 工厂方法模式(Factory Method Pattern):定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。
- 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。
- 建造者模式(Builder Pattern):将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
- 原型模式(Prototype Pattern):用于创建对象的一种方式,通过复制一个已经存在的对象实例来创建新的实例。
结构型设计模式(Structural Design Pattern):
结构设计模式的主要目的是将不同的类和对象组合在一起以形成更大或更复杂的结构。主要关注类之间的联系方式。
结构设计包括:
- 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口。
- 桥接模式(Bridge Pattern):将抽象部分与实现部分分离,使它们都可以独立地变化。
- 装饰者模式(Decorator Pattern):动态地给一个对象添加一些额外的职责。
- 组合模式(Composite Pattern):将对象组合成树形结构以表示"部分-整体"的层次结构。
- 外观模式(Facade Pattern):为子系统中的一组接口提供一个一致的界面,外部应用程序只需与这个外观对象交互。
- 享元模式(Flyweight Pattern):运用共享技术,有效地支持大量细粒度的对象。
行为型设计模式(Behavioral Design Pattern):
行为设计模式涉及对象之间的职责分配
行为设计模式解释对象如何交互
行为设计模式描绘了难以在运行时跟踪的复杂控制流。它将复杂的控制流转化为对象之间的关系。
- 策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并使它们可以互换。
- 观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
- 命令模式(Command Pattern):将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。
- 职责链模式(Chain of Responsibility Pattern):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
- 状态模式(State Pattern):允许对象在其内部状态改变时改变它的行为。
- 访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
- 迭代器模式(Iterator Pattern):用于提供一种顺序访问一个聚合对象(如集合)中各元素,而不暴露该对象的内部表示。它定义了一种方式来访问聚合对象中的各个元素,而不需要暴露聚合对象的内部结构。
什么是设计模式
**定义:**设计模式是软件设计经验的总结;软件设计中反复出现的设计问题的成功解决方案;其核心思想是软件复用;设计模式主要用于软件的本地设计
**辨析:**架构模式是一种高层设计,适合整体软件设计;设计模式适合本地软件设计。
**构成要素:**1. 名称(上下文context)2.问题 3.解决方案 4.影响
开闭原则open and close principle:开闭原则是禁止修改模块中已有的代码,但模块的行为是可以扩展的expanded。许多设计模式都是为了满足开闭原则而设计的。
工厂模式(Factory Pattern)
问题
连接硬件和软件的接口有很多,如蓝牙、Wi-Fi、USB等。
我们同一个软件如何适应所有的界面?
工厂方法
将创建代码从main函数中抽象出来;然后将其放入专门用于创建对象的函数中
**优点:**工厂方法隐藏了创建对象的细节,简化了客户端程序。工厂方法实现了创建和使用分离的思想
**缺点:**工厂必须要知道产品对象的细节,这不符合开闭原则;同样的main方法也必须要知道工厂方法的细节
简单工厂模式The Simple Factory Pattern
工厂方法没有将创建工作彻底从客户端类中提取出来。
客户端类还必须知道创建对象的细节简单工厂模式构建另一个独立的类,负责创建对象
Creator : Creative类,它使用静态factory()方法到构造一个特定的产品类
产品(接口):父类
具体产品:子类
**优点:**一个客户仅简单地使用由创建者类构造的产品类;模式中实现了职责分离;可以添加不影响客户端的新产品子类
**缺点:**当添加新产品时,静态工厂方法将会被修改。 因此不能满足开闭原则
静态工厂方法不能被继承 inherited。 这是一个独奏类。
工厂模式Factory Pattern
工厂模式改进了简单工厂模式:(添加了工厂的接口)
- 层次结构创建者类的单独创建者类
- 不同的创造者创造出不同的产品
工厂方法是动态的;满足了开闭原理;工厂模式的工厂方法不包含创建产品的逻辑判断(Polymorph)
抽象工厂模式Abstract Factory Pattern
主要角色:
- 抽象工厂(Abstract Factory): 定义了创建一组产品的接口,通常包含多个创建方法,每个方法对应一个具体产品的创建。
- 具体工厂(Concrete Factory): 实现了抽象工厂接口,负责创建一组具体的产品。
- 抽象产品(Abstract Product): 定义了一类产品的接口,可以是一系列相关或相互依赖的产品。
- 具体产品(Concrete Product): 实现了抽象产品接口,是具体工厂所创建的对象。
工作流程:
- 客户端通过实例化具体工厂对象来创建一组产品。
- 具体工厂对象负责创建一组相关的产品,保证这些产品是相互兼容的。
- 客户端通过抽象产品接口使用这些产品,而不需要关心具体产品的类名。
优点:
- 产品一致性: 由同一工厂创建的产品族是一致的,相互之间可以良好地配合使用。
- 易于替换: 可以轻松替换具体工厂,从而改变整个产品族的实现。
- 封装变化: 客户端与具体产品的实现解耦,不需要关心具体产品的类名,只需关心产品的接口。
缺点:
- 扩展困难: 增加新的产品族可能需要修改抽象工厂的接口,这可能导致一些实现类的变动。
- 复杂性增加: 随着产品族的增加,抽象工厂的接口和具体工厂的实现可能变得复杂。
辨析工厂和抽象工厂
- 产品层次结构:
- 工厂模式(Factory Method Pattern): 侧重于单一产品的创建,每个具体工厂类负责创建一种类型的产品。它通过将对象的实例化延迟到子类来提供一种创建对象的接口。
- 抽象工厂模式(Abstract Factory Pattern): 侧重于一组相关或相互依赖的产品的创建,每个具体工厂类负责创建一整个产品族。它提供一组创建对象的接口,这些对象之间可以相互协作。
- 创建方法:
- 工厂模式: 使用工厂方法,每个具体工厂类都有一个创建方法,用于实例化特定类型的产品。
- 抽象工厂模式: 使用一组创建方法,每个方法负责创建一类相关的产品。一个工厂可以创建多个产品。
- 关注点:
- 工厂模式: 关注于一个产品的创建和实例化过程,通过将这个过程延迟到子类来实现具体的产品创建。
- 抽象工厂模式: 关注于一组相关产品的创建,强调这组产品之间的一致性和兼容性。
- 扩展性:
- 工厂模式: 通过添加新的具体工厂类和产品类来扩展。
- 抽象工厂模式: 通过添加新的具体工厂类和产品类来扩展,但扩展的是整个产品族而不是单一产品。
选择使用场景:
- 工厂模式: 当只有一个抽象产品类,而具体产品的类有多个时,适合使用工厂模式。
- 抽象工厂模式: 当有多个相关产品族,且系统需要保证这些产品族之间的一致性和兼容性时,适合使用抽象工厂模式。
单例模式(Singleton pattern)
在软件设计中,有时需要用一个类来只产生一个对象
**定义:**单例模式是保证一个类只有一个唯一的实例并提供一个全局访问点
实现:
- 私有的构造方法:单例模式的实现机制是将类的构造方法声明为私有类型。
- 静态的公共的返回对象实例:为了创建一个 privates 类型的对象,需要一个静态方法 getInstance()只返回一个对象实例
- 私有的静态的单例对象
优点:
- 单例模式严格控制客户端程序访问其唯一的实例
- 模式的 Singleton 类可以轻松更改,以允许类创建一定数量的对象
复合模式Composite pattern
场景:在某些情况下,人们不加区别地对待部分和整体
复合模式是一种整体与部分并重的设计模式。即复合对象和简单对象的接口统一处理。复合对象composite object是由一个或多个相似对象组成的对象,每个对象都有相似的功能。复合对象的思想是客户端以相同的方式处理单个对象和一组对象。复合模式将对象组合成树结构来表示部分和整个层次结构。
**组成:**组件:实现共享接口的所有类的默认行为;Leaf :单个组件;复合:表示一组组件;客户端:通过组件接口操作复合对象。实际过程与leaf和composite不同
优点:
- 定义了由叶对象和复合对象组成的类层次结构
- 复合模式通过以一致的方式处理叶子和复合对象,简化了客户端的过程
- 更容易添加新类型的组件
**安全复合模式:**安全模式:复合类中存在add()、remove()等方法。然而,这些方法不存在于叶子对象中。缺点:复合对象和叶子对象的接口不同
透明复合模式:透明复合模式下,接口add() , remove() 和 getChild()在所有组件的类中声明,包括叶对象和复合对象。优点: 所有组件都有相同的接口
适配器模式Adapter pattern
**定义:**通过适配器来匹配不同接口的设计模式称为适配器模式
在软件设计中,为了解决接口不一致的问题,需要一个适配器类Adapter
分类 :1. 类适配器模式 2.对象适配器模式
类适配器模式Class Adapter Pattern
在类适配器模式中,适配器继承了目标接口,并同时持有被适配者的引用。通过继承目标接口,适配器使得自己可以被客户端代码看作是目标接口的一部分,同时通过持有被适配者的引用,实际上是调用被适配者的方法来完成适配。
主要角色:
- 目标接口(Target): 定义客户端使用的标准接口。
- 被适配者(Adaptee): 需要被适配的类。
- 适配器(Adapter): 继承目标接口,同时持有被适配者的引用,实现目标接口的方法。
特点:
- 通过继承实现适配。
- 只能适配被适配者的子类。
对象适配器模式Object Adapter Pattern
在对象适配器模式中,适配器通过持有被适配者的实例来实现适配。适配器实现目标接口,并在实现目标接口的方法中调用被适配者的方法。
主要角色:
- 目标接口(Target): 定义客户端使用的标准接口。
- 被适配者(Adaptee): 需要被适配的类。
- 适配器(Adapter): 持有被适配者的实例,实现目标接口的方法,并在方法中调用被适配者的方法。
特点:
- 通过组合实现适配。
- 可以适配被适配者的任何子类。
作用
-
接口转换
-
添加新界面
适配器模式也称为转换器模式、变压器模式、包装器模式等。
迭代器模式Iterator Design Pattern
应用场景
在不知道一个聚合对象的内部结构的情况下,迭代一个聚合数据结构。该模式使得客户端可以在不知道元素具体组织结构的情况下遍历聚合对象的元素。
主要角色:
- 迭代器(Iterator): 定义了访问和遍历聚合对象元素的接口,包括获取下一个元素、判断是否还有元素等方法。
- 具体迭代器(ConcreteIterator): 实现迭代器接口,负责实现具体的遍历算法,追踪当前位置等。
- 聚合(Aggregate): 定义创建迭代器对象的接口,即工厂方法,可以是一个抽象类或接口。
- 具体聚合(ConcreteAggregate): 实现聚合接口,返回一个合适的具体迭代器实例。
- 客户端(Client): 使用迭代器模式的客户端,通过迭代器遍历聚合对象中的元素。
工作流程:
- 客户端通过聚合对象获取迭代器。
- 客户端使用迭代器的方法依次访问聚合对象中的元素。
优点:
- 分离了聚合对象的遍历行为和具体元素的表示,使得迭代算法更加灵活。
- 简化了聚合的接口,客户端无需关心聚合的内部结构。
- 支持多种遍历方式,可以有不同的迭代器实现。
访问者模式(Visitor Pattern)
应用场景
主要目的是将算法与其所操作的对象的结构分离开来。访问者模式使得可以在不修改这些对象的情况下,定义作用于这些对象的新操作。
主要角色:
- 访问者(Visitor): 定义了要访问的对象的接口,为每个具体元素类型都提供了访问方法。
- 具体访问者(ConcreteVisitor): 实现了访问者接口,提供了对具体元素类型的访问方法,即定义了实际的操作。
- 元素(Element): 定义了一个接口,声明了接受访问者的方法,即
accept
方法。 - 具体元素(ConcreteElement): 实现了元素接口,提供了具体的
accept
方法,通常会调用访问者的相应方法。 - 对象结构(Object Structure): 是一个包含元素的集合,提供了一个接受访问者的方法,用于遍历元素集合。
工作流程:
- 访问者通过调用元素的
accept
方法开始访问对象结构中的元素。 - 元素的
accept
方法会调用访问者的相应方法,将自身传递给访问者。 - 访问者执行相应的操作,可以根据需要调用元素的方法。
优点:
- 将数据结构与算法解耦,使得新的操作可以在不修改现有元素结构的情况下添加。
- 增加新的访问者相对容易,因为不需要修改现有元素类。
- 支持对元素结构的不同访问方式。
缺点:
-
添加特定的新具体元素ConcreteElement 类很困难。
-
如果要添加新的具体 Element 类,则必须在每个 ConcreteVisitor 类中添加 ConcreteElement 类的访问方法。
命令模式(Command Pattern)
场景:
程序包含一些相互关联的对象interrelated objects,每个对象提供一些有限的和特定的功能。
针对用户的请求,系统提供了一些处理程序,这些处理程序也使用了其他对象的功能
设计的目的是实现责任分离responsibility separation
客户端通常是一个图形界面程序,帮助用户选择参数。客户端调用调用者对象,调用者根据用户的选择调用。接收者对象接收者对象包含实际的处理程序。
它将请求封装成一个对象,从而允许使用不同的请求、队列或者日志来参数化其他对象,并且能够支持可撤销的操作。
主要角色:
- 命令接口(Command): 定义了执行操作的接口,通常包括一个
execute
方法。 - 具体命令(ConcreteCommand): 实现了命令接口,负责执行具体的操作,通常包含了对接收者的引用。
- 接收者(Receiver): 知道如何实施与执行一个请求相关的操作。
- 调用者/请求者(Invoker): 负责调用命令对象执行请求。
- 客户端(Client): 创建具体命令对象,并设置其接收者。
工作流程:
- 客户端创建具体命令对象,将其关联到特定的接收者。
- 调用者持有命令对象,并在需要执行请求时调用命令对象的
execute
方法。 - 具体命令对象通过调用接收者的方法执行请求。
优点:
- 解耦调用者和接收者: 调用者无需知道接收者的具体类,只需要知道命令接口即可。
- 支持撤销和恢复操作: 命令对象可以保存状态,从而支持撤销和恢复操作。
- 支持命令的队列和日志: 可以很容易地将命令对象组织成队列,实现命令的排队和记录。
- 满足开闭原则
架构设计方法
简介
一般设计过程:
-
定位Locating架构上的重要需求 (ASR)
-
捕获Capturing质量属性要求
-
选择、生成、定制和分析设计决策以实现这些要求achieving those requirements
设计策略(Design strategy)
设计策略包括对架构设计方法至关重要的三个想法:
-
分解
分解是设计的起点。当设计被分解时,质量属性需求(包括约束)也可以被分解并分配给分解的元素。
-
根据架构重要需求 (ASR)进行设计
ASR驱动架构设计。架构上重要的需求( ASR )是对架构产生深远影响的需求。如果没有这样的要求,架构很可能会截然不同。
新手架构师可能会一次专注于一个 ASR。通过经验和教育,您将采用模式来帮助您设计多个 ASR。
对未满足的非 ASR 的三个选项:
- 如果已经接近满足要求,可以看看是否可以放宽要求
- 您可以重新确定需求的优先级并重新审视设计
- 您可以汇报您无法满足要求
-
生成并测试
看待设计的一种方式是将其视为生成和测试的过程。该方法将特定的设计视为假设:设计满足要求。
设计解决方案是使用项目可用的**抵押品collateral **创建的。抵押品可包括
-
现有系统Existing systems
现有系统为重用需求提供了强大的保证。
一种常见的特殊情况是现有系统是同一栋楼的系统。当您开发系统时会发生这种情况。
另一个特殊情况是当您必须将现有遗留系统合并为单个系统时。
-
项目可用的框架Frameworks available to the project
框架是一种部分设计,提供特定领域中常见的服务。
框架的设计提供了初步的设计假设。
框架存在于许多领域,从Web应用程序到中间件系统。
-
已知的架构模式Known architecture patterns
模式是给定上下文中常见问题的已知解决方案。
编目的体系结构模式(可能通过策略进行增强)应该被视为您正在构建的设计假设的候选者。
-
设计清单Design checklists
-
域分解A domain decomposition
初始设计假设的另一个选择来自于执行域分解例如,大多数面向对象的分析和设计过程都是这样开始的,识别域中的参与者和实体。
**选择测试:**三个用于检验假设的来源:质量属性分析技术;质量属性的设计检查表;架构上的重要要求 ( ASR )
生成下一个假设:应用测试后,您可能就完成了。另一方面,您可能仍然有一些担忧。使用策略集来帮助改进您的设计,以便您能够满足这些出色的质量属性要求
终止进程:当设计已经满足ASR、或者已经耗尽设计预算时终止设计。对于未完成的设计,有:1. 以最佳假设继续实施,但放宽一些 SAR 。这是最常见的情况。 2.争取更多预算用于设计和分析、重新设计以及恢复生成和测试。
-
属性驱动设计ADD方法
定义
属性驱动设计(ADD)方法是对架构设计策略的封装。
ADD是一种迭代方法
迭代过程:
- 系统的一部分进行设计
- 该部分的所有 ASR
- 创建并测试该零件的设计
ADD原则:基于质量属性的分解过程的软件架构。
ADD输入
需求:功能、质量和约束。实际上,等待所有需求都被了解意味着项目永远不会完成,因为随着时间的推移,需求不断到达项目。
ASR:ADD 可以在知道一组 ASR 后开始ASR集在开始后发生变化,那么设计很可能需要重新设计。
上下文:上下文描述给出了两个重要的信息
- 正在设计的系统的边界是什么
- 所设计的系统必须与之交互的外部系统、设备、用户和环境条件是什么
ADD输出
结构视图草图sketches of architectural views:这些视图一起将识别架构元素及其关系或交互的集合。包括分解视图、C&C视图和分配视图。
ADD过程
五步法:
- 选择要设计的系统元素
- 识别所选元素的ASR
- 为所选元素生成设计解决方案
- 清点剩余需求并选择下一次迭代的输入
- 重复步骤1-4直至完成
选择元素
ADD 的工作原理是从系统中尚未设计的部分开始。
第一次执行ADD 步骤将产生一个广泛而浅显的设计yield a broad, shallow design,该设计将产生一组新确定的架构元素
第一次迭代将创建一个元素集合,这些元素共同构成整个系统。第二次迭代采用一个元素并对其进行设计,从而产生更细粒度的元素。第三次迭代将采用另一个元素,整个系统的后代之一,依此类推。
迭代策略strategies:ADD有两种主要的优化策略
- 广度优先Breadth first:意味着所有第二级元素都先于任何第三级元素设计,依此类推
- 深度优先Depth first :意味着在开始第二条下行链之前完成一条下行链
影响迭代的因素:
- 人员可用性Personnel availability可能决定细化策略。
- 风险缓解Risk mitigation可能决定细化策略。这个想法是将有风险的部分设计到足够的深度。
- 推迟Deferral某些功能或质量属性问题可能需要采用混合方法。
识别元素的ASR
效用树Utility Tree
效用树比其他方法具有优势:它指导利益相关者确定 QA 需求的优先级。
实用程序Utility作为根节点。效用是系统整体优点的体现。质量属性Quality attributes形成中层。应用场景Scenarios形成效用树的叶子
场景优先级Prioritize Scenarios:用于确定实用程序树中 ASR 优先级的两个因素是业务价值和架构影响。
为所选元素生成设计方案
这是ADD的核心。
- 您最初的候选设计可能会受到某种模式的启发,并可能通过一种或多种策略进行增强。
- 然后,您可以通过考虑设计清单来完善此候选设计。
验证和细化需求
第四步是一个测试步骤,适用于您在本次迭代的第一步中选择详细说明的元素的设计。第四步的可能结果之一是回溯,这意味着重要的要求没有得到满足。
您尚未满足的 ASR 可能与以下内容相关
-
分配给父元素的质量属性要求
如何对不满意的ASR采取行动
询问:1. 这个策略会提高质量属性吗? 2.该策略是否应该与另一种策略结合使用?3.有哪些权衡考虑因素?
-
父元素的功能责任
对于功能职责:将职责添加到现有模块或新创建的模块中:
- 职责分配给包含类似职责的模块
- 当模块太复杂时将其分成几个部分
- 分配给包含具有相似质量属性特征的职责的模块
-
对父元素的一个或多个约束
修改设计或尝试放松约束:
- 修改设计以适应约束
- 放宽约束
最后检查设计,并重复以上四个步骤。
直到:1. 对团队信任度较高:架构草图可用时。2. 团队信任较低:需要额外的设计环节。 终止ADD流程。
构架评估Architecture Evaluation
介绍
作用
评估的作用:架构是系统成功的重要贡献者important contributor,确保架构能够提供所期望的一切是有意义的
三种形式
-
设计师在设计过程中进行评估by the designer
每次设计师做出关键设计决策或完成设计里程碑时makes a key design decision or completes a design milestone,都应该评估所选择的和竞争的替代方案。设计人员的评估是生成和测试generate-and-test方法的测试部分。
评价示例:
使用插件或者自行开发实现网格功能吗?
是否支持跨平台?
现有系统如何使用?分析到什么程度
- 决定的重要性
- 潜在替代品potential alternatives的数量。替代方案越多,评估它们的时间就越多
- 足够好而不是完美Good enough as opposed to perfect。不要在决定上花费超过其价值的时间。
-
设计过程中同行的评估by peers
设计过程中存在候选体系结构或至少存在一个连贯的可评审部分的任何点进行。
应该有固定的时间,至少几个小时,可能半天。
步骤:
- 审阅者reviewers确定许多质量属性场景来推动审阅
- 架构师architect提出要评估的架构部分
- 审阅者 reviewers可以访问每个场景满足
- 审查时发现潜在问题Potential problems
-
架构设计完成后由外部人员进行分析by outsiders
外部评估者可以制定目标、关注架构。外部是相对的:1. 开发项目之外 2.项目所在业务部门之外但在同一公司内 3.公司外部。
选择外部人员的条件
- 选择外部人员是因为他们拥有专业知识或经验
- 有关对所检查的系统很重要的质量属性的知识
- 成功评估架构的经验
原则上,外部团队可以评估完整的架构、不完整的架构或架构的一部分。在实践中,它们往往被用来评估完整的体系结构。
背景因素
- 可用的材料Artifacts
- 结果是公开的还是私密的
- 评估人员evaluator数量及技能水平
- 利益相关者stakeholders的数量和身份
- 如何理解业务目标business goal
架构权衡分析方法(ATAM)
定义
ATAM揭示了架构满足特定质量目标的程度,并提供了对质量目标如何相互作用的深入了解,即它们如何权衡。
参与者
ATAM需要三个群体的参与和相互合作:
-
评估小组evaluation team
评估团队为:
- 该组是项目外部的external
- 它通常由三到五个人组成。 团队的每个成员都被分配了许多特定的角色。
- 无论如何,他们需要被视为有能力、公正的局外人。
团队内部角色
- 队长Team Leader:设置评价;与客户协调,签订合同;组建评估小组;发布最终报告
- 评估负责人Evaluation Leader:运行评估;有助于情景的引出;促进根据架构评估场景;便于现场分析
- 场景抄写员Scenario Scribe
- 会议记录抄写员Proceedings Scribe
- 发问者Questioner
-
项目决策者Project decision makers
定义:有权代表开发项目发言或有权要求对其进行更改(项目经理、重要客户)。一个基本规则是架构师必须自愿参与。
-
架构利益相关者Architecture stakeholders
包括:开发人员、测试人员,集成人员,维护人员,性能工程师,用户,正在考虑的系统以及其他系统交互的系统构建者。
输出
- 架构的简洁的演示concise presentation
- 阐明业务目标
- 以质量属性场景表示的优先质量属性要求
- 一组风险和非风险
- 一组风险主题
- 将架构决策映射到质量要求
- 一组已确定的灵敏度sensitivity和权衡点tradeoff points
ATAM术语表
灵敏度Sensitivity ——对某一质量属性有显着影响的架构决策
权衡点Tradeoff points——对更多质量属性有显着影响的架构决策
风险Risks ——风险是可能导致不良后果的架构决策
无风险 Nonrisks——经分析认为安全的架构决策
各个阶段
阶段_ | 活动 | 参加者 | 典型持续时间 |
---|---|---|---|
0 | 合作和准备 | 评估小组领导和项目关键决策者 | 根据需要非正式地进行,可能需要几周的时间 |
1 | 评价1 | 评估小组和项目决策者 | 1 至 2 天,然后中断1 至 3周 |
2 | 评估2(续) | 评估团队、项目决策者和利益相关者 | 2天 |
3 | 后续 | 评估团队及评估委托人 | 1周 |
合作与准备Partnership and preparation
在第 0 阶段,评估团队领导层和关键项目决策者举行非正式会议,制定演习细节:
- 项目代表向评审人员介绍项目情况
- 两个小组共同商定后勤工作,例如会议的时间和地点
- 利益相关者的初步名单达成一致
- 他们负责向评估团队交付任何架构文档
- 评估团队负责人解释经理和架构师在第一阶段需要展示哪些信息
评估阶段
评估阶段包括1和2两个阶段。
内容包括:
-
介绍ATAM
第一步要求评估负责人向聚集的项目代表展示 ATAM。这次用来讲解大家将要遵循的流程领导者将使用标准演示简要描述 ATAM 步骤和评估结果。
-
当前的业务驱动因素
了解系统的背景以及推动其发展的主要业务驱动因素:
- 系统最重要的功能
- 任何相关的技术、管理、经济或政治限制
- 与项目相关的业务目标和背景
- 主要利益相关者
- 架构驱动因素
-
现在的结构
首席架构师以适当的详细程度进行了描述架构的演示:
- 设计并记录了多少架构
- 有多少时间可用
- 行为和质量要求的性质
演示具体内容:
推动架构要求(2 – 3 张幻灯片)
重要的架构信息(4 – 8 张幻灯片)上下文图,模块或层视图,组件和连接器视图,部署视图
架构方法、模式或策略(3 – 6 张幻灯片)商业现成(COTS) 产品的使用以及如何选择/集成它们。跟踪 1 到 3 个最重要的用例场景(1 - 3 张幻灯片)。跟踪 1 到 3 个最重要的变更场景(1 - 3 张幻灯片)。与满足驱动架构要求相关的架构问题/风险(2 - 3 张幻灯片)。术语表(1 张幻灯片)
-
确定架构方法
通过了解架构方法来分析架构评估
- 团队将很好地了解架构师在设计系统时使用的模式和方法。
- 在这短短的一步中,评估团队只需对明显的模式和方法进行分类。
-
生成质量属性实用程序树utility tree
通过称为效用树的机制详细阐明。
实用程序树使需求变得具体评估团队与项目决策者合作,确定、优先考虑和细化系统最重要的质量属性目标,这些目标以场景的形式表示。
-
分析架构方法
一次性检查排名最高的场景:
- 架构师被要求解释该架构如何支持每一项
- 提问者探究架构师用于执行场景的架构方法
- 记录相关的架构决策并识别和分类它们风险、非风险、敏感点和权衡
- 场景演练引发对可能的风险、非风险、敏感点或权衡点的讨论
-
集思广益并确定场景的优先级
情景头脑风暴的目的是把握更大利益相关者群体的脉搏。
在此步骤中,评估团队要求利益相关者集思广益,对利益相关者的个人角色具有操作意义的场景进行讨论 。
收集场景后,必须对它们进行优先级排序prioritized
-
首先,利益相关者被要求合并merge他们认为代表相同行为或质量问题的场景
-
然后他们投票vote给那些他们认为最重要的场景
-
-
分析架构方法
收集场景并确定优先级后,评估团队将指导架构师执行第 7 步中排名最高的场景。
架构师解释了相关的架构决策如何有助于实现每一个架构决策。
-
目前的结果
最后将收集到的信息进行总结和呈现:
记录的架构方法;场景集及其优先级;效用树;发现的风险;记录的非风险;找到的敏感点和权衡点。
后续工作Follow-up
后续阶段,评估团队制作并提交书面最终报告
但这个阶段的本质是团队的自省和提升
事后会议上,团队讨论哪些进展顺利,哪些进展不佳
团队成员寻求改进他们履行职责的方式,以便下一次评估能够更加顺利或更有效
团队评估过程中花费了多少精力适当的几个月后,团队领导联系评估客户以评估演习的长期效果,以便比较成本和收益
轻量级架构评估Lightweight Architecture Evaluation
ATAM 需要评估团队大约20 到 30 个人日的努力,架构师和利益相关者的工作量甚至更多大型且成本高昂的项目上投入这么多时间才有意义。
对于较小、风险较低的项目,轻量级架构评估(LAE)练习可能会在一天内完成。
流程:
- 出示 ATAM ( 0 小时)
- 目前的业务驱动因素 ( 0.25 小时)
- 当前架构( 0.5 小时)
- 确定架构方法( 0.25 小时)
- 生成质量属性实用程序树(可变0.5 小时 – 1.5小时)
- 分析架构方法( 2-3 小时)
- 集思广益并确定场景的优先级 ( 0 小时)
- 分析架构方法 ( 0 小时)
- 当前结果 ( 0.5 小时)
成本效益分析方法(CBAM)
方法介绍
CBAM(成本效益分析方法)是一种软件系统经济建模方法,以分析其架构为中心。
它提供了对技术和经济问题以及架构决策的评估。
软件架构师或决策者希望最大化系统收益与实现设计成本之间的差异。
**技术对成本的影响:**利益相关者决定他们是否应该:使用冗余硬件;故障转移;负载均衡节省该项目的成本,投资另一个项目,例如:冗余软件
和ATAM的关系
**区别:**目的地不同,ATAM关心产品本身,它为软件架构师提供了一种评估技术权衡的方法;CBAM关心经济因素,它考虑成本、收益、风险和进度影响。
**联系:**都从业务目标出发,而最终作用于质量属性场景。ATAM识别与从业务目标中得出的质量属性场景相关的一组关键架构决策。CBAM直接考虑业务目标的成本和收益。
基础方法
CBAM 背后的想法是架构策略影响质量属性,而这些反过来又为利益相关者提供一些好处。
CBAM 可以帮助利益相关者根据其**成本价值value for cost (VFC)**选择架构策略
VFC=效益/成本
效用与响应Utility and Response
我们将效益 benefit称为效用utility。每个架构策略都为利益相关者提供特定级别的实用性。效用是系统利益相关者获得的利益。效用基于所考虑的每个场景相对于其预期响应值的重要性。
CBAM 实际上使用一组场景(通过改变响应值生成),而不是像 ATAM 中的单个值。这引出了效用响应曲线的概念CBAM 结构场景通常包括:刺激、环境和响应。
我们可以将一组效用度量和一组相应的响应度量之间的每个关系描绘为一个图——效用响应曲线utility-response curve(URC)
URC的四个关键指标:
- 最好情况(0.1 秒 RT 对于一个人来说是瞬时的,所以 0.03 并不重要)= 100
- 最坏情况(最低要求)= 0
- 当前(相对于最佳和最差)= x%
- 期望(相对于最佳和最差)= y%
我们需要为所有场景生成URC曲线
场景优先级
为了描述每个场景的相对重要性,权重t 通过两步投票进行分配
- 利益相关者对场景进行投票以建立它们之间的顺序
- 然后,利益相关者将权重1分配给评分最高的场景以及其他场景的一小部分
架构策略
架构师确定从当前质量属性响应级别转向所需级别的架构策略
对于每个策略,我们可以得出:
- 每种情况下响应的预期值
- 架构策略对其他感兴趣属性的影响
- 实施架构策略的成本估算
确定效益和标准化
计算一个架构在所有质量场景下的整体效用
某个架构的整体效用=∑(某场景的预期效用-当前效用)*场景相对重要权重
计算VFC
某个架构的VFC=某架构的整体效用/某架构的成本
使用这个VFC分数,可以对架构策略进行排序;然后可以使用此排序来确定实施各种策略的最佳顺序。
基于VFC选择架构策略
战略 | 成本 | 总效益 | 策略VFC | 策略排名 |
---|---|---|---|---|
1 | 100 | 180 | 180% | 1 |
2 | 200 | 320 | 160% | 3 |
3 | 300 | 500 | 167% | 2 |
CBAM步骤
- 整理场景: 优先选择前三分之一(1/3)
- 细化场景:确定场景的最佳、最差、当前和期望情况的质量属性响应级别
- 优先考虑场景:消除一半场景(1/6)
- 为每个场景的当前级别和所需级别分配效用
- 制定场景架构策略并确定质量属性响应级别
- 使用插值确定架构策略的预期效用值
- 从架构策略中获得的总收益
- 在成本约束下选择基于VFC的架构策略
- 凭直觉确认结果
软件产品线 Software Product Lines
简介
软件产品线的核心目的是促进重用以降本增效。
定义:软件产品线:一组软件密集型系统,共享一组通用的、受管理的功能,满足特定细分市场或任务的特定需求,并以规定的方式从一组通用的核心资产开发而来。
优势:当产品线成功建立后,每个可重用资产都保存在核心资产库core asset base中。因为它可以应用于多个系统,并且重复使用它比重新发明它更便宜。该产品线改善了成本、质量和上市时间。
基于软件产品线的系统构建流程:
- 访问Accessing核心资产库中的适当资产asset
- 根据正在构建的系统的需要,运用更改点variation points以配置这些资产
- 组装Assembling该系统
软件产品线复用的部分
- 需求
- 架构设计
- 软件的元素(如界面、文档、过程、模型)
- 建模和分析
- 测试相关(计划、流程、用例、数据、工具)
- 项目计划(预算、工期)
- 流程、方法和工具
- 人员
- 演示系统
- 缺陷消除机制
一个软件产品线需要支持至少三个产品才能够获得收益。
产品线的范围product line’s scope
**定义:**产品线的范围是关于组织愿意构建哪些系统作为其产品线的一部分,以及不愿意构建哪些系统的声明。
范围界定过程的输入来自组织的战略规划人员、营销人员、可以对类似系统进行分类的领域分析师, 和技术专家。
范围定义对于产品线架构师至关重要,因为范围定义了产品线所有成员的共同点,以及产品彼此不同的具体方式。
范围不能够太少(要大于3个),也不能太多(过于复杂,难以管理)
产品线中的可变性Variability
可变性的质量属性与软件产品线关系最为密切。
可变性是可修改性的一种特殊形式,涉及核心资产适应不同产品环境中的使用的能力。
软件产品线的可变性目标是随着时间的推移,可以轻松地构建和维护产品线中的产品。
具体见 质量属性.其它质量属性.可变性
作用
在核心资产存储库的所有资产中,软件架构起着最核心的作用。
这既有战术原因,也有战略原因。
战术原因The Tactical Reason是架构在产品线中构建产品中发挥的重要性。建立成功的产品线的本质是区分恒定性和多样性。软件架构非常适合处理这种变化。
战略原因The Strategic Reason是其在现有产品线领域之外赋予组织的能力有关。架构可以作为组织进入新业务领域的跳板。
变易机制Variation Mechanisms
变易机制支撑着软件产品线
克隆并拥有:复制已有的代码,并根据要求更改其中一部分。这个方式的问题在于他无法拓展。假设21 个中的每一个 产品包含大约100个模块。如果每个产品允许每个模块不同,那么维护人员可能需要处理2,100 个模块。
因此我们引入变易机制。
我们不维护很多版本,而是使用多个公共模块,并且只识别小的各种模块
我们引入一种变异机制,例如延迟绑定
变化机制将让我们维护一个能够适应应用程序变化范围的单一模块。
三个主要的全局架构变易机制
- 包含或省略Inclusion or omission元素。
- 包含不同数量Inclusion of a different number的复制元素。
- 选择具有相同接口,但行为或质量属性特征不同的不同版本的元素。
影响
- 实施或学习和使用所需的技能集,具体的变化机制需要编程
- 构建或获取创建变异机制所需工具的一次性成本
- 执行变更机制的经常性成本和时间
- 变化机制对质量的影响,例如可能的性能损失或内存消耗
- 对机制可维护性的影响
常见变异机制
序号 | 变异机制 | 与构建核心资产相关的属性 | 构建产品时与行使变异机制相关的属性 |
---|---|---|---|
1 | 遗产专门化或概括特定类 | 成本:中;等技能:面向对象语言 | 利益相关者:产品开发商;工具:编译器;成本:中等 |
2 | 元件替代 | 成本:中;等技能:接口定义 | 利益相关者:产品开发人员、系统管理员;工具:编译器;成本:低 |
3 | 加一个插件 | 成本:高;技能:框架编程 | 利益相关者:最终用户;工具:无;成本:低 |
4 | 模板 | 成本:中等;技能:抽象 | 利益相关者:产品开发人员、系统管理员;工具:无;成本:中等 |
5 | 参数(包括文本预处理器) | 成本:中等;技能:无需特殊技能 | 利益相关者:产品开发人员、系统管理员、最终用户;工具:无;成本:低 |
6 | 发电机Generator | 成本:高;技能:生成式编程 | 利益相关者:系统管理员、最终用户;工具:发电机;成本:低 |
7 | 运行时条件Runtime conditionals | 成本:中等;技能:无需特殊技能 | 利益相关者:无;工具:无;成本:无开发成本、一些性能成本 |
8 | 配置器Configurator | 成本:中等;技能:无需特殊技能 | 利益相关者:产品开发商;工具:配置器;成本:低到中等 |
如何设计产品线
1.识别变异点
在开发过程中几乎可以随时识别变体
需求获取过程中发现了一些变化;其他,在架构设计期间;还有一些,在实施过程中
2.支持变异点
使用变异机制以支持变异点
3.评估产品线适用性的架构
重点关注变化点,以确保:
- 他们是合适的
- 它们提供足够的灵活性来覆盖产品线的预期范围
- 快速构建产品
- 它们不会造成不可接受的运行时性能成本
产品线关键问题
关键问题是什么:技术并不是产品线的唯一障碍;组织、流程和业务问题同样重要;配置管理对于任何项目来说也是一项重要活动。
软件产品线会失败的原因:
- 缺乏具有足够控制力和远见的领头人。
- 管理层未能提供持续和坚定的支持。
- 中层管理人员不愿放弃对项目的专制控制。
- 未能明确确定业务目标
- 一有困难迹象就放弃着手处理
- 未能对员工进行适当的方法培训,未能充分解释或证明变革的合理性
一个好的策略是启动一个小型但可见的试点项目,以展示软件产品线的定量优势
如何组织和优化产品线
什么时候开始使用软件产品线:
-
当经理命令组织使用该方法时,就会出现自上而下的采用。
-
当产品级别的设计人员和开发人员意识到他们不必要地重复彼此的工作并开始共享资源并开发通用核心资产时,就会发生自下而上的采用。
主动模式的产品线
在主动产品线中,组织使用范围的全面定义来定义产品系列。
它使组织能够做出影响最深远的战略决策。
主动模型需要初始投资,但比反应模型返工更少。
反应式模型产品线
反应式模型不太重视前期规划和战略方向设定。相反,组织让自己按照市场的指示行事。
反应式模型完全依赖于返工,初始投资很少。
产品线的演变
-
外部来源
元素的新版本将由其供应商发布
外部创建的元素可以添加到产品线中
可以将功能添加到产品线中
-
内部来源
必须确定产品添加的新功能是否在该产品线的范围内
最新技术应用
两种组织结构
- 所有开发工作都集中在一起 ,不存在独立的核心资产组。所有软件开发都集中在一个单元中。
- 独立的核心资产单元 设立专门单位负责核心资产基础的开发和维护。
组织进入新业务领域的跳板。
变易机制Variation Mechanisms
变易机制支撑着软件产品线
克隆并拥有:复制已有的代码,并根据要求更改其中一部分。这个方式的问题在于他无法拓展。假设21 个中的每一个 产品包含大约100个模块。如果每个产品允许每个模块不同,那么维护人员可能需要处理2,100 个模块。
因此我们引入变易机制。
我们不维护很多版本,而是使用多个公共模块,并且只识别小的各种模块
我们引入一种变异机制,例如延迟绑定
变化机制将让我们维护一个能够适应应用程序变化范围的单一模块。
三个主要的全局架构变易机制
- 包含或省略Inclusion or omission元素。
- 包含不同数量Inclusion of a different number的复制元素。
- 选择具有相同接口,但行为或质量属性特征不同的不同版本的元素。
影响
- 实施或学习和使用所需的技能集,具体的变化机制需要编程
- 构建或获取创建变异机制所需工具的一次性成本
- 执行变更机制的经常性成本和时间
- 变化机制对质量的影响,例如可能的性能损失或内存消耗
- 对机制可维护性的影响
常见变异机制
序号 | 变异机制 | 与构建核心资产相关的属性 | 构建产品时与行使变异机制相关的属性 |
---|---|---|---|
1 | 遗产专门化或概括特定类 | 成本:中;等技能:面向对象语言 | 利益相关者:产品开发商;工具:编译器;成本:中等 |
2 | 元件替代 | 成本:中;等技能:接口定义 | 利益相关者:产品开发人员、系统管理员;工具:编译器;成本:低 |
3 | 加一个插件 | 成本:高;技能:框架编程 | 利益相关者:最终用户;工具:无;成本:低 |
4 | 模板 | 成本:中等;技能:抽象 | 利益相关者:产品开发人员、系统管理员;工具:无;成本:中等 |
5 | 参数(包括文本预处理器) | 成本:中等;技能:无需特殊技能 | 利益相关者:产品开发人员、系统管理员、最终用户;工具:无;成本:低 |
6 | 发电机Generator | 成本:高;技能:生成式编程 | 利益相关者:系统管理员、最终用户;工具:发电机;成本:低 |
7 | 运行时条件Runtime conditionals | 成本:中等;技能:无需特殊技能 | 利益相关者:无;工具:无;成本:无开发成本、一些性能成本 |
8 | 配置器Configurator | 成本:中等;技能:无需特殊技能 | 利益相关者:产品开发商;工具:配置器;成本:低到中等 |
如何设计产品线
1.识别变异点
在开发过程中几乎可以随时识别变体
需求获取过程中发现了一些变化;其他,在架构设计期间;还有一些,在实施过程中
2.支持变异点
使用变异机制以支持变异点
3.评估产品线适用性的架构
重点关注变化点,以确保:
- 他们是合适的
- 它们提供足够的灵活性来覆盖产品线的预期范围
- 快速构建产品
- 它们不会造成不可接受的运行时性能成本
产品线关键问题
关键问题是什么:技术并不是产品线的唯一障碍;组织、流程和业务问题同样重要;配置管理对于任何项目来说也是一项重要活动。
软件产品线会失败的原因:
- 缺乏具有足够控制力和远见的领头人。
- 管理层未能提供持续和坚定的支持。
- 中层管理人员不愿放弃对项目的专制控制。
- 未能明确确定业务目标
- 一有困难迹象就放弃着手处理
- 未能对员工进行适当的方法培训,未能充分解释或证明变革的合理性
一个好的策略是启动一个小型但可见的试点项目,以展示软件产品线的定量优势
如何组织和优化产品线
什么时候开始使用软件产品线:
-
当经理命令组织使用该方法时,就会出现自上而下的采用。
-
当产品级别的设计人员和开发人员意识到他们不必要地重复彼此的工作并开始共享资源并开发通用核心资产时,就会发生自下而上的采用。
主动模式的产品线
在主动产品线中,组织使用范围的全面定义来定义产品系列。
它使组织能够做出影响最深远的战略决策。
主动模型需要初始投资,但比反应模型返工更少。
反应式模型产品线
反应式模型不太重视前期规划和战略方向设定。相反,组织让自己按照市场的指示行事。
反应式模型完全依赖于返工,初始投资很少。
产品线的演变
-
外部来源
元素的新版本将由其供应商发布
外部创建的元素可以添加到产品线中
可以将功能添加到产品线中
-
内部来源
必须确定产品添加的新功能是否在该产品线的范围内
最新技术应用
两种组织结构
- 所有开发工作都集中在一起 ,不存在独立的核心资产组。所有软件开发都集中在一个单元中。
- 独立的核心资产单元 设立专门单位负责核心资产基础的开发和维护。