系统工程体系与实践 第 5 篇:系统架构设计与实现
摘要
本文将带你深入了解系统架构设计的核心方法和实现流程,帮助你掌握从概念到部署的完整架构设计能力。你将学到系统概念定义与需求分析、系统架构设计基础、多架构视图设计方法、系统分析与权衡研究,以及系统实现、集成与验证的完整流程。
学习目标
阅读完本文后,你将能够:
- 定义系统概念:掌握从问题识别到系统概念定义的完整流程
- 设计系统架构:理解架构设计的基本原则和方法
- 应用多视图架构:掌握功能、逻辑、物理等多视图架构设计
- 进行权衡分析:了解系统分析和权衡研究的方法
- 管理实现集成:掌握系统实现、集成与验证的最佳实践
一、系统概念定义与需求分析
1.1 问题识别与机会分析
系统开发始于问题识别和机会分析。这一阶段的目标是明确”为什么要开发这个系统”,即识别需要解决的问题或可以利用的机会。
问题识别:问题可能来自多个来源。客户可能明确表达了需求或痛点;市场分析可能发现了未被满足的用户需求;技术进步可能创造了新的可能性;竞争压力可能要求改进现有系统;法规变化可能要求新的系统功能。问题识别需要区分表面症状和根本原因。表面症状是显而易见的现象,根本原因是导致这些现象的深层次因素。例如,用户抱怨系统响应慢是表面症状,根本原因可能是架构不合理、算法低效、资源不足等。只有找到根本原因,才能设计出有效的解决方案。
机会分析:问题背后往往隐藏着机会。识别问题后,需要分析解决这些问题能带来什么价值。价值可以是经济价值(降低成本、增加收入)、战略价值(提升竞争力、开辟新市场)、社会价值(改善生活质量、保护环境)等。机会分析需要评估价值的规模和确定性。有些机会价值巨大但不确定,有些机会价值确定但规模有限。机会分析还需要考虑可行性——技术是否可行、经济是否合理、时间是否允许。
利益相关者分析:问题和机会的识别需要考虑所有相关利益相关者。利益相关者包括客户(系统的最终用户)、购买者(做出购买决策的人)、操作者(日常操作系统的技术人员)、维护者(负责系统维护的人员)、监管者(制定相关法规的机构)、合作伙伴(供应商、渠道商等)。不同的利益相关者可能有不同的甚至冲突的需求和期望。利益相关者分析识别所有相关方,分析他们的需求和期望,评估他们的影响力和关注度。利益相关者分析的结果指导需求优先级排序和权衡决策。
1.2 系统概念定义
问题识别和机会分析之后,需要定义系统的初步概念。系统概念是对系统”是什么”的高层描述,为后续的详细设计和开发提供方向。
使命定义:系统使命是对系统目的的简洁陈述,回答”系统为什么要存在”这个问题。使命定义应该从用户角度出发,描述系统为用户提供的价值,而不是从技术角度描述系统的功能。例如,一个智能家居系统的使命可能是”让家庭生活更便捷、更安全、更节能”,而不是”提供远程控制、自动化、能源管理功能”。使命定义为整个项目提供了方向和约束,后续的所有决策都应该与使命一致。
愿景陈述:愿景描述系统成功后的理想状态。愿景比使命更加具体,描述系统在未来3-5年应该达到的状态。愿景应该具有激励性,能够激发团队的创造力;应该具有可实现性,不是空中楼阁;应该具有可度量性,能够判断是否实现。愿景陈述为项目提供了长期目标,指导战略决策。
操作概念:操作概念(ConOps)描述系统将在什么样的环境下使用、谁将使用系统、系统如何被使用。操作概念包括使用场景、用户角色、使用流程、环境条件等。操作概念帮助团队理解系统的使用背景,确保设计符合实际使用情况。操作概念通常采用用例、用户故事、场景描述等表示方法。
能力需求:能力需求是系统应该具备的高层能力,而不是具体的功能需求。能力需求描述系统”应该能够做什么”,而不是”如何做”。例如,“系统应该能够在火灾发生时自动报警”是能力需求,“系统应该使用烟雾传感器检测火灾”是功能需求(实现方式)。能力需求为功能需求提供了框架,功能需求是实现能力需求的具体方式。
约束条件:约束条件是对系统的限制,包括技术约束(必须使用的技术或标准)、性能约束(必须达到的性能指标)、成本约束(预算限制)、时间约束(交付时间要求)、法规约束(必须符合的法规)、环境约束(使用环境条件)。约束条件限制了设计空间,必须在约束内寻找可行的解决方案。
1.3 需求工程
需求工程是系统开发的基础活动,包括需求获取、需求分析、需求规格化、需求验证、需求管理等活动。
需求获取:需求获取是从利益相关者那里收集需求的过程。需求获取的方法包括访谈(与利益相关者一对一或小组访谈)、问卷(向大量用户发放问卷)、观察(观察用户实际工作或使用现有系统)、研讨(组织利益相关者研讨会)、原型(通过原型获取反馈)。需求获取的挑战在于:利益相关者可能不知道自己想要什么(只知道自己不想要什么)、利益相关者可能表达不清楚、不同利益相关者的需求可能冲突。需求获取需要良好的沟通技巧,需要引导利益相关者明确需求,需要发现隐藏的假设和约束。
需求分析:需求获取得到的需求往往是模糊、矛盾、不完整的。需求分析对获取的需求进行分析、整理、细化。需求分析活动包括:需求分类(将需求分类为功能需求、性能需求、接口需求、约束需求等)、需求关联(识别需求之间的关系,如依赖关系、冲突关系)、需求优先级排序(根据价值、成本、风险等因素排序需求)、需求可行性分析(评估需求的技术可行性和经济可行性)。需求分析的结果是结构化的、一致的需求集合。
需求规格化:需求规格化是将需求写成正式的需求规格文档。好的需求规格应该具备以下特性:完整的(覆盖所有相关需求)、一致的(需求之间没有矛盾)、无歧义的(每个需求只有一种解释)、可验证的(能够验证需求是否被满足)、可追踪的(能够追踪需求的来源和实现)、可修改的(文档结构支持需求变更而不破坏整体)。需求规格通常使用自然语言(如需求陈述”系统应该…“)、形式化语言(如SysML需求图)、或两者结合。需求规格是后续设计和开发的基础,也是需求管理的基础。
需求验证:需求验证确保需求规格是正确的、完整的、一致的。需求验证的方法包括:需求评审(由专家和利益相关者评审需求规格)、原型验证(通过原型验证需求的可行性)、场景分析(通过使用场景验证需求的覆盖)、一致性检查(检查需求之间的逻辑关系)。需求验证的目的是在早期发现需求问题,避免后期返工。需求缺陷发现越晚,修复成本越高。
需求管理:需求管理是对需求变更进行管理的过程。需求在项目过程中几乎必然变化,需求管理确保变更得到控制。需求管理活动包括:需求基线管理(建立需求的基线版本,作为后续工作的基础)、变更控制(评估变更的影响,决定是否接受变更)、需求追溯(维护需求与设计、实现、测试之间的追溯关系)、需求度量(度量需求的稳定性、变更频率等指标)。需求管理的目标是平衡稳定性(需求不能频繁变化)和适应性(需要响应合理的变化)。
1.4 需求分类
需求可以从多个角度分类,理解不同类型需求的特点有助于更好地管理和实现需求。
功能需求与非功能需求:功能需求描述系统应该做什么,是系统的行为和功能。非功能需求描述系统应该如何表现,是系统的质量属性。功能需求通常是可观察的,如”系统应该能够发送电子邮件”。非功能需求包括性能需求(响应时间、吞吐量)、可靠性需求(可用性、故障率)、安全性需求(机密性、完整性)、可维护性需求(可修改性、可测试性)、可用性需求(易学性、易用性)等。非功能需求往往比功能需求更难实现,需要在架构层面进行考虑。
用户需求与系统需求:用户需求是从用户角度描述的需求,使用用户的语言和概念。系统需求是从系统角度描述的需求,使用技术和工程语言。用户需求需要转化为系统需求,这个过程称为需求工程。例如,用户需求”我想要快速得到搜索结果”转化为系统需求”系统应该在2秒内返回搜索结果”。用户需求和系统需求的区分确保设计真正满足用户需要,而不是设计人员想象的用户需要。
业务需求与技术需求:业务需求是从业务角度描述的需求,关注业务目标和价值。技术需求是从技术角度描述的需求,关注技术实现。业务需求驱动技术需求,技术需求支持业务需求。例如,业务需求”降低运营成本30%“驱动技术需求”系统自动化率达到80%“。业务需求和技术需求的区分确保技术服务于业务目标,而不是为了技术而技术。
强制性需求与愿望性需求:强制性需求是必须满足的需求,不满足则系统不可接受。愿望性需求是希望满足但非必须的需求。区分强制性需求和愿望性需求有助于优先级排序和资源分配。强制性需求必须保证实现,愿望性需求可以根据资源和时间情况灵活处理。
衍生需求:衍生需求不是直接来自利益相关者,而是从其他需求衍生出来的。例如,从”系统需要在户外使用”可以衍生出”系统需要防水防尘”的需求。衍生需求往往是非功能需求或约束需求,需要需求分析人员识别和补充。
二、系统架构设计基础
2.1 架构的定义
软件架构和系统架构有多个定义,但共同的认识是:架构是系统的基本组织结构,包括组件、组件之间的关系、组件与环境之间的关系,以及指导设计和演进的原则。
架构不仅描述系统的静态结构(组件和关系),还包括设计决策的原理和权衡。架构是设计决策的高层抽象,关注系统的整体组织,而不是实现细节。架构定义了系统的”骨架”或”蓝图”,后续的详细设计遵循架构设定的框架。
架构与详细设计的区别在于抽象层次。架构是高层的、战略性的,关注系统的整体结构。详细设计是低层的、战术性的,关注组件的内部设计。架构决策对系统有广泛和持久的影响,详细设计决策的影响范围较小。架构错误是致命的,很难在后期修正;详细设计错误是局部问题,可以在后期修正。
架构设计是多目标优化问题。好的架构应该满足多个目标:功能需求(实现系统功能)、质量属性(性能、可靠性、安全性等)、约束条件(技术、成本、时间约束)。这些目标往往相互竞争,需要在相互竞争的目标之间找到平衡。架构设计是权衡的艺术,没有唯一的正确答案,只有多个各有优劣的可行方案。
2.2 架构设计原则
架构设计有一些经过验证的原则,这些原则不是绝对的规则,而是在实践中证明有用的指导方针。
关注点分离:关注点分离原则将系统划分为多个模块,每个模块关注一个特定的关注点。关注点可以是功能(如用户管理、数据访问)、层次(如表示层、业务层、数据层)、方面(如日志、安全、事务)。关注点分离降低了认知负担,使得每个模块可以独立理解和修改。关注点分离的实现方式包括模块化、分层、面向方面编程等。
高内聚低耦合:内聚是模块内部元素之间相关性的度量,耦合是模块之间依赖关系的度量。高内聚意味着模块内部元素紧密相关,共同完成一个明确的功能。低耦合意味着模块之间弱关联,一个模块的变化对其他模块影响小。高内聚低耦合的模块易于理解、易于测试、易于维护、易于重用。实现高内聚低耦合的方法包括:定义清晰的接口、隐藏内部实现、最小化模块间的依赖、使用依赖注入等。
抽象与封装:抽象是隐藏细节、展示必要信息的机制。封装是将数据和操作数据的方法捆绑在一起,并隐藏内部实现。抽象和封装降低了复杂度,提供了清晰的接口,使得模块可以独立变化而不影响其他模块。抽象和封装是面向对象设计的基础,但也适用于其他设计范式。
单一职责原则:一个模块应该只有一个改变的理由。换句话说,一个模块应该只做一件事,并做好。如果一个模块有多个职责,它就应该分解为多个模块。单一职责原则使得模块更加聚焦、更加简单、更加易于理解和维护。单一职责原则是高内聚的表现。
开放封闭原则:模块应该对扩展开放,对修改封闭。这意味着模块的行为应该可以扩展,而无需修改模块的源代码。开放封闭原则通过抽象和多态实现——定义稳定的接口,新的功能通过实现接口添加。开放封闭原则使得系统可以适应变化,而不会引入回归缺陷。
依赖倒置原则:高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。依赖倒置原则通过接口抽象实现,高层和低层都依赖接口,而不是直接依赖。依赖倒置原则降低了模块间的耦合,使得模块可以独立演化和替换。
接口隔离原则:不应该强迫客户端依赖它们不使用的接口。接口应该小而专注,而不是大而全。接口隔离原则通过将大接口分解为多个小接口实现,客户端只依赖它需要的接口。接口隔离原则减少了不必要的依赖,提高了系统的灵活性。
最少知识原则(迪米特法则):一个对象应该对其他对象有尽可能少的了解。最少知识原则通过中介者模式、门面模式等实现,减少对象之间的直接依赖。最少知识原则降低了耦合,使得系统更加模块化。
2.3 架构视图
系统是复杂的,单一视图无法捕捉系统的所有方面。架构视图从特定的角度描述系统,每个视图强调系统的某些方面,忽略其他方面。多个视图的组合提供了对系统的全面理解。
4+1视图模型:4+1视图模型是经典的架构视图框架,由Philippe Kruchten提出。4+1视图包括逻辑视图(Logical View)、进程视图(Process View)、物理视图(Physical View)、开发视图(Development View),以及用例视图(Use Case View,即”+1”)。
逻辑视图描述系统的功能需求,将系统分解为功能组件和对象。逻辑视图关注系统的功能组织,典型的建模工具包括类图、对象图、状态图。逻辑视图的主要受众是系统分析师和设计人员。
进程视图描述系统的并发和同步方面,关注进程、线程、同步机制。进程视图关注系统的运行时行为,典型的建模工具包括活动图、序列图、状态图。进程视图的主要受众是系统集成人员和性能分析师。
物理视图描述系统的物理部署,关注硬件节点、通信链路、网络拓扑。物理视图关注系统的物理组织,典型的建模工具包括部署图、网络图。物理视图的主要受众是系统管理员和部署人员。
开发视图描述系统的开发组织,关注模块、子系统、库、包。开发视图关注系统的静态组织,支持开发工作的分工和协作。典型的建模工具包括包图、组件图。开发视图的主要受众是开发人员和项目经理。
用例视图(场景视图)描述系统的使用场景,是其他视图的驱动。用例视图关注系统的功能需求,典型的建模工具包括用例图、用户故事。用例视图的主要受众是用户和需求分析师。
其他架构视图框架:除了4+1视图模型,还有其他架构视图框架。IEEE 1471(后来发展为ISO/IEC 42010)定义了架构描述的标准,强调利益相关者和关注点。西门子视角(Rozanski & Woods)增加了数据视图和安全视图。实际项目中,可以根据项目的具体需要选择或定义合适的架构视图。
2.4 架构模式
架构模式是经过验证的架构解决方案,针对特定的架构问题。架构模式不是具体的实现,而是解决方案的模板,可以在具体项目中实例化和调整。
分层架构:分层架构将系统组织为多个层次,每层提供特定的服务,依赖下层的服务。典型的分层包括:表示层(用户界面)、应用层(业务逻辑)、领域层(领域对象)、数据访问层(数据持久化)、基础设施层(通用服务)。分层架构的优点是关注点分离、易于理解和维护、支持技术替换(每层可以独立替换技术)。分层架构的缺点是性能损失(多层调用)、层次僵化(可能不适合所有场景)。
管道过滤器架构:管道过滤器架构将系统组织为一系列处理步骤(过滤器),数据在步骤之间流动(管道)。每个过滤器独立处理输入数据,产生输出数据。管道过滤器架构的优点是模块化、可重用、可并发。典型应用包括编译器(词法分析、语法分析、语义优化、代码生成)、数据处理系统(ETL流程)。管道过滤器架构的缺点是不适合交互式系统、数据转换开销。
客户服务器架构:客户服务器架构将系统划分为客户端和服务器,客户端请求服务,服务器提供服务。客户服务器架构的优点是分布性、可扩展性、易于维护。客户服务器架构有多个变体:两层架构(胖客户端)、三层架构(应用服务器)、多层架构(多个中间层)。客户服务器架构的缺点是网络依赖、服务器瓶颈、安全风险。
事件驱动架构:事件驱动架构中,组件通过事件进行通信。一个组件发布事件,其他组件订阅并响应事件。事件驱动架构的优点是松耦合、异步性、可扩展性。事件驱动架构的缺点是调试困难、一致性保证复杂。事件驱动架构典型应用于用户界面系统(GUI事件)、消息系统(消息队列)、物联网系统(传感器事件)。
微服务架构:微服务架构将系统组织为一组小型、独立的服务,每个服务实现特定的业务功能,服务之间通过轻量级通信机制(通常是HTTP API)协作。微服务架构的优点是独立部署、技术多样性、可扩展性、容错性。微服务架构的缺点是分布式复杂性、数据一致性挑战、运维复杂性。微服务架构适合大型、复杂、需要快速演化的系统。
发布订阅架构:发布订阅架构中,发布者发布消息到主题,订阅者订阅感兴趣的主题。发布者和订阅者通过消息代理解耦,不直接通信。发布订阅架构的优点是解耦、异步性、多播。发布订阅架构的缺点是消息顺序保证复杂、消息代理单点故障。发布订阅架构典型应用于消息系统、事件通知系统。
黑板架构:黑板架构用于解决没有确定性解决方案的问题。系统包含多个知识源(专用解决方案)、黑板(共享数据结构)、控制器(协调知识源)。知识源观察黑板,当知识源能够做出贡献时,修改黑板数据。黑板架构典型应用于信号识别、语音识别、图像识别等领域。
选择架构模式需要考虑多个因素:问题特征(问题类型、复杂度)、质量属性要求(性能、可靠性、可扩展性等)、团队能力(团队熟悉的模式)、技术约束(可用技术、标准)。架构模式可以组合使用,不同模式用于不同的部分或层次。
三、系统分析与权衡研究
3.1 系统分析方法
系统分析是评估系统特性、预测系统行为、比较备选方案的过程。系统分析使用定量和定性方法,为架构决策提供依据。
定量分析方法:定量分析使用数学模型和数值计算,提供可度量的分析结果。定量分析方法包括:
性能模型:性能模型预测系统的性能指标,如响应时间、吞吐量、资源利用率。性能模型可以是分析模型(如排队论模型)、仿真模型(如离散事件仿真)、测量模型(基于实际测量)。性能分析帮助识别性能瓶颈,评估架构方案是否满足性能需求。
可靠性模型:可靠性模型预测系统的可靠性指标,如可用性、故障率、平均修复时间。可靠性模型可以是分析模型(如可靠性框图、马尔可夫模型)、仿真模型。可靠性分析帮助识别单点故障,评估架构方案的可靠性。
安全性模型:安全性模型评估系统的安全特性,如机密性、完整性、可用性。安全性分析包括威胁建模(识别潜在威胁)、攻击树分析(分析攻击路径)、风险评估(评估风险等级)。安全性分析帮助识别安全漏洞,设计安全机制。
成本模型:成本模型评估系统的生命周期成本,包括开发成本、生产成本、运营成本、维护成本。成本分析帮助进行经济权衡,选择成本效益最佳的方案。
定性分析方法:定性分析基于专家判断和经验,提供定性的评估结果。定性分析方法包括:
检查表:检查表是预先定义的问题清单,用于评估架构的特定方面。例如,可维护性检查表可能包括”代码是否模块化”、“是否有足够的注释”、“是否有测试”等问题。检查表的优点是结构化、可重复,缺点是可能遗漏重要问题。
场景分析:场景分析通过使用场景评估架构。定义典型使用场景或关键场景,“走查”架构如何支持这些场景。场景分析可以发现架构的缺陷和不足,评估架构的适用性。
权衡分析:权衡分析比较多个架构方案在多个质量属性上的表现。权衡分析可以是定量的(如性能评分、成本评分),也可以是定性的(如专家排序)。权衡分析帮助选择最满意的架构方案。
3.2 权衡研究方法
权衡研究是系统分析的核心活动,用于在多个备选方案之间做出选择。权衡研究需要系统化的方法,确保选择是合理的、可追溯的。
决策矩阵:决策矩阵是最常用的权衡研究方法。决策矩阵将备选方案作为行,评估标准作为列,在每个单元格中评分。评分可以是定量的(如成本、性能的具体数值),也可以是定性的(如高、中、低)。可以为不同标准设置权重,反映其相对重要性。加权评分总和最高的方案是最优方案。决策矩阵的优点是结构化、透明、易于理解。缺点是评分和权重具有主观性,可能掩盖重要的定性因素。
Pugh矩阵:Pugh矩阵是决策矩阵的变体,特别适合架构选择。Pugh矩阵选择一个基准方案,其他方案与基准方案比较,在每个标准上评为”更好”、“相同”或”更差”。Pugh矩阵的优点是减少了绝对评分的主观性,缺点是需要选择合适的基准方案。
层次分析法(AHP):AHP是一种更复杂的决策方法,通过两两比较确定标准的权重和方案的得分。AHP首先构建层次结构(目标-标准-方案),然后对标准进行两两比较,确定权重;对每个标准,对方案进行两两比较,确定得分。AHP提供一致性检验,确保判断的逻辑一致性。AHP的优点是结构严谨,缺点是复杂度高,需要更多的判断。
成本效益分析:成本效益分析比较方案的成本和效益,选择效益成本比最高的方案。成本可以是开发成本、运营成本;效益可以是经济收益、战略价值、社会价值。成本效益分析的挑战在于量化效益,特别是战略价值和社会价值。成本效益分析适合有明确经济指标的项目。
多准则决策分析(MCDA):MCDA是一类方法的总称,用于在多个准则下做出决策。MCDA方法包括TOPSIS(逼近理想解排序法)、ELECTRE(淘汰选择法)、PROMETHEE(偏好排序法)等。MCDA方法各有特点,适用于不同的决策场景。
敏感性分析:无论使用哪种权衡研究方法,都应该进行敏感性分析。敏感性分析检验结论对假设和参数的敏感性。如果关键参数的微小变化导致结论变化,结论的稳健性就差。敏感性分析可以识别关键驱动因素,帮助决策者理解结论的可靠性。
3.3 架构权衡分析方法(ATAM)
架构权衡分析方法(Architecture Tradeoff Analysis Method, ATAM)是由SEI(Software Engineering Institute)开发的架构评估方法,特别关注质量属性的权衡。
ATAM的基本假设是:架构决策不能同时优化所有质量属性,必须在相互竞争的质量属性之间进行权衡。例如,高性能可能损害可修改性,高安全性可能损害可用性。ATAM的目标是识别这些权衡,做出明智的决策。
ATAM包括以下步骤:
步骤1:收集利益相关者需求:识别所有利益相关者,收集他们对系统的质量属性需求。需求可以形式化为质量属性场景(quality attribute scenarios),描述刺激(stimulus)、环境(environment)、响应(response)。例如,“正常工作期间,当1000个用户同时访问系统时,系统响应时间应在2秒内”是一个性能场景。
步骤2:从架构角度理解需求:架构师展示架构的概览,解释关键架构决策。这些决策是后续分析的基础。
步骤3:生成质量属性效用树:将质量属性需求组织为效用树,根节点是质量属性(如性能、可修改性、安全性),子节点是具体场景。效用树帮助组织需求,识别优先级。
步骤4:分析架构方法:对于每个高优先级场景,分析架构如何满足该场景。识别相关的架构方法(architecture tactics,实现质量属性的具体设计决策),评估这些方法对场景的影响。同时,识别架构方法对其他质量属性的影响(tradeoff)。
步骤5:生成和评估权衡点:综合前面的分析,识别权衡点——架构决策对多个质量属性有不同影响的地方。权衡点是架构分析的关键发现,需要在决策中明确考虑。
步骤6:生成风险、非风险、敏感点:风险是可能导致质量属性问题的架构决策或假设。非风险是有正面影响的架构决策或假设。敏感点是对关键参数敏感的架构决策或假设。
步骤7:生成和评估风险缓解策略:对于识别的风险,制定缓解策略。缓解策略可能包括修改架构、增加验证、制定应急计划等。
ATAM的优点是结构严谨、关注权衡、可重复、可追溯。ATAM的缺点是复杂度高、需要专门的技能、时间和资源投入大。ATAM适合大型、复杂、关键系统的架构评估。
3.4 质量属性场景
质量属性场景是描述质量属性需求的结构化方式。场景是质量属性需求的具体实例,使得需求更加明确和可验证。
质量属性场景包含六个要素:
刺激源(Source of Stimulus):产生刺激的实体。刺激源可能是用户、系统、外部实体。
刺激(Stimulus):到达系统的条件。刺激可能是事件、输入、条件变化。
环境(Environment):系统受到刺激时的状态。环境可能是正常、过载、降级、故障等。
制品(Artifact):受到刺激的系统部分。制品可能是整个系统、某个组件、某个资源。
响应(Response):系统对刺激的反应。响应可能是活动、状态变化、返回值。
响应度量(Response Measure):度量响应质量的指标。响应度量可能是响应时间、吞吐量、错误率等。
例如,一个性能场景可能是:“正常工作期间(环境),当1000个用户同时访问(刺激),由用户(刺激源)发起,系统(制品)应该在2秒内返回响应(响应),响应时间应小于2秒(响应度量)。”
一个可用性场景可能是:“系统正常运行期间(环境),当服务器发生故障(刺激),由硬件故障(刺激源)引起,系统(制品)应该在10秒内切换到备用服务器(响应),切换时间应小于10秒(响应度量)。”
质量属性场景使得需求更加明确和可验证。场景可以用于需求分析、架构设计、测试验证。场景还帮助识别架构方法——如何设计架构以满足场景要求。
四、系统实现、集成与验证
4.1 系统实现
系统实现是将设计转化为实际系统的过程。对于软件系统,实现是编码;对于硬件系统,实现是制造;对于混合系统,实现包括软件和硬件。
实现策略:实现可以采用不同的策略。自顶向下实现从高层开始,逐步细化到底层。自底向上实现从底层开始,逐步组装到高层。中间相遇(meet-in-the-middle)结合了自顶向下和自底向上,从两端开始,在中间汇合。自顶向下有利于保持整体视角,但底层可能设计不合理。自底向上有利于底层设计合理,但可能偏离整体目标。中间相遇试图结合两者的优点。
并行实现:大型系统可以分解为多个部分,并行实现。并行实现可以缩短总开发时间,但需要额外的协调工作。并行实现需要明确的接口定义,使得部分可以独立开发。并行实现需要集成策略,确保部分能够正确集成。并行实现需要配置管理,追踪并行的开发线。
组件采购与自制:系统实现需要决定哪些组件采购(使用COTS组件),哪些组件自制。采购组件可以降低开发成本和风险,但限制了设计灵活性。自制组件可以完全控制设计,但增加了开发成本和风险。决策因素包括:是否是非核心功能(非核心功能倾向于采购)、是否有可用产品(有可用产品倾向于采购)、是否是差异化因素(差异化因素倾向于自制)、成本效益分析(综合成本比较)。
技术债务管理:实现过程中可能产生技术债务——为了快速交付而牺牲的设计质量或代码质量。技术债务需要管理,不能无限累积。技术债务管理包括:识别技术债务(代码审查、静态分析、度量)、评估技术债务(影响程度、修复成本)、制定偿还计划(何时偿还、如何偿还)、避免不必要的技术债务(良好的实践和设计)。
质量内建:质量内建是指开发人员负责质量,而不是测试人员负责质量。质量内建实践包括:单元测试(开发人员编写和运行单元测试)、代码审查(同行审查代码质量)、静态分析(自动检查代码质量问题)、持续集成(频繁集成,早期发现集成问题)。质量内建的理念是:缺陷发现越早,修复成本越低。
4.2 系统集成
系统集成是将组件集成为完整系统的过程。集成是系统开发的关键环节,集成的复杂度往往被低估。
集成策略:集成可以采用不同的策略。大爆炸集成(Big Bang)一次性集成所有组件。大爆炸集成的优点是简单,缺点是问题难以定位(不知道是哪个组件的问题)。增量集成逐步集成组件,每次集成后进行测试。增量集成的优点是问题容易定位,缺点是集成次数多、需要仔细规划。增量集成可以进一步分为:自顶向下集成(从高层开始,逐步集成底层)、自底向上集成(从底层开始,逐步集成高层)、三明治集成(结合自顶向下和自底向下,从两端开始,在中间汇合)。
持续集成:持续集成是一种集成实践,开发人员每天多次将代码集成到主分支,每次集成自动运行构建和测试。持续集成的目标是快速发现集成问题,避免集成偏离过远。持续集成需要自动化构建和测试的支持,需要开发人员遵循良好的编码和集成实践(频繁提交、不破坏构建、快速修复问题)。持续集成的价值在于:快速反馈、降低集成风险、提高软件质量、支持频繁发布。
接口管理:集成的核心挑战是接口管理。接口定义了组件之间的交互契约。接口管理包括:接口定义(定义接口的语法和语义)、接口文档(记录接口的定义和用法)、接口版本(接口的演化管理)、接口测试(验证接口的正确性)。接口管理需要明确的责任分配(谁负责定义、实现、测试接口)、明确的变更流程(接口变更需要通知相关方、评估影响、更新文档)、明确的冲突解决机制(当接口需求冲突时如何解决)。
集成测试:集成测试验证组件之间能够正确协作。集成测试不同于单元测试(验证单个组件)和系统测试(验证完整系统)。集成测试关注接口和交互,发现集成相关的缺陷,如接口不匹配、数据格式错误、时序问题、资源竞争等。集成测试的策略包括:基于测试的集成(基于测试需求选择集成顺序)、基于风险集成的集成(先集成高风险组件)、基于功能集成的集成(按功能集成相关组件)。
4.3 系统验证
系统验证确认系统是否正确地实现了需求,回答”我们是否正确地制造了产品?“这个问题。
验证方法:验证可以采用多种方法。
审查(Review)是人工检查文档、代码、模型。审查可以发现设计缺陷、需求遗漏、不一致等问题。审查的类型包括:需求审查、设计审查、代码审查、测试计划审查等。审查需要明确的流程(准备、会议、跟踪修复)、明确的角色(作者、审查者、协调者)、明确的记录(问题清单、修复状态)。
仿真(Simulation)是在模型上模拟系统行为,评估系统特性。仿真可以早期验证设计,而不需要构建实际系统。仿真的类型包括:性能仿真(评估性能)、可靠性仿真(评估可靠性)、行为仿真(验证系统行为)。仿真需要模型(系统的数学或逻辑表示)、仿真器(执行仿真的工具)、实验设计(定义仿真场景和参数)。
分析(Analysis)是使用数学方法分析系统特性。分析的类型包括:性能分析(排队论、网络理论)、可靠性分析(可靠性框图、故障树分析)、安全性分析(威胁建模、攻击树)。分析需要模型(系统的抽象表示)、分析方法(数学或逻辑方法)、分析工具(支持分析的软件)。
测试(Test)是在系统或组件上执行操作,观察结果,验证行为。测试是验证的主要方法,将在下一节详细讨论。
验证层次:验证在多个层次上进行。
单元测试验证单个组件或模块。单元测试由开发人员编写和运行,是开发过程的一部分。单元测试应该快速、自动化、覆盖关键路径。
集成测试验证组件之间的集成。集成测试发现接口问题、集成问题。集成测试通常由集成团队负责,需要专门的测试环境和测试数据。
系统测试验证完整系统是否满足需求。系统测试从用户角度验证系统功能、性能、可靠性等。系统测试通常由测试团队负责,需要接近真实环境的测试环境。
验收测试验证系统是否满足用户需要。验收测试通常由用户或用户代表执行,是系统交付前的最后一道关卡。
4.4 系统确认
系统确认确认系统是否满足用户需要,回答”我们是否制造了正确的产品?“这个问题。验证关注实现是否正确,确认关注产品是否有价值。
确认方法:确认可以采用多种方法。
用户试用是在真实或接近真实的环境中使用系统,收集用户反馈。用户试用可以发现需求的偏差、可用性问题、实际使用问题。用户试用的关键是选择合适的用户(代表性用户)、提供足够的支持(培训、文档)、收集系统的反馈(结构化的反馈机制)。
Beta测试是向一组选定的用户提供系统,在实际环境中使用。Beta测试比用户试用规模更大、时间更长、环境更真实。Beta测试可以发现用户试用不能发现的问题(如长期使用问题、边缘情况)。
现场试点是在有限的范围内实际部署系统,作为全面部署的试点。现场试点是最接近真实使用环境的确认方法。现场试点可以发现真实环境的问题(如与现有系统的集成、实际性能、实际可用性)。
A/B测试是比较两个或多个版本的系统,看哪个版本效果更好。A/B测试常用于Web系统和移动应用,通过随机分配用户到不同版本,比较用户行为指标(如点击率、转化率)。A/B测试可以客观评估不同方案的价值。
确认与验证的关系:确认和验证是互补的活动。验证确保系统实现了需求,确认确保系统有价值。没有验证,确认无法判断系统是否正确实现。没有确认,验证可能验证了错误的需求。理想情况下,确认应该在早期开始(通过原型、用户故事),验证贯穿整个开发过程,最后在真实环境中进行全面确认。
五、系统架构设计图表讲解
sequenceDiagram autonumber participant Stakeholder as 利益相关者 participant RE as 需求工程 participant Architect as 架构设计 participant Analysis as 系统分析 participant Tradeoff as 权衡研究 participant Implementation as 系统实现 participant Integration as 系统集成 participant Validation as 系统验证 participant System as 最终系统 Note over Stakeholder,System: 系统架构设计与实现全流程 Stakeholder->>RE: 1. 提出问题和机会 RE->>RE: 2. 需求获取与分析<br/>利益相关者分析<br/>需求分类与优先级 RE->>Architect: 3. 需求规格化<br/>功能需求<br/>质量属性需求<br/>约束条件 Architect->>Architect: 4. 系统概念定义<br/>使命与愿景<br/>操作概念<br/>能力需求 Architect->>Analysis: 5. 提出多个架构方案 Analysis->>Analysis: 6. 系统分析<br/>定量分析<br/>定性分析<br/>场景分析 Analysis->>Tradeoff: 7. 提交分析结果 Tradeoff->>Tradeoff: 8. 权衡研究<br/>决策矩阵<br/>ATAM<br/>风险评估 Tradeoff->>Architect: 9. 推荐最优方案 Architect->>Stakeholder: 10. 架构评审与确认 Stakeholder->>Implementation: 11. 批准实施 Implementation->>Implementation: 12. 系统实现<br/>编码/制造<br/>组件采购<br/>质量内建 Implementation->>Integration: 13. 组件交付 Integration->>Integration: 14. 系统集成<br/>增量集成<br/>接口管理<br/>集成测试 Integration->>Validation: 15. 集成系统提交 Validation->>Validation: 16. 系统验证<br/>审查/仿真/分析/测试<br/>多层级验证 Validation->>Stakeholder: 17. 系统确认<br/>用户试用<br/>Beta测试 Stakeholder->>System: 18. 验收通过<br/>系统交付使用 System->>RE: 19. 使用反馈<br/>需求变更 RE->>Architect: 20. 架构演进<br/>持续改进
图表讲解:这个序列图展示了系统架构设计与实现的完整流程。这是一个从需求到验证的迭代过程,包含多个反馈循环。
流程开始于利益相关者提出问题和机会。需求工程进行需求获取与分析,包括利益相关者分析(识别所有相关方)、需求分类(功能需求、质量属性需求、约束需求)、需求优先级排序(根据价值、成本、风险排序)。需求分析的输出是结构化的、一致的需求集合。
需求规格化将需求写成正式的需求规格文档。需求规格包括功能需求(系统应该做什么)、质量属性需求(性能、可靠性、安全性等)、约束条件(技术、成本、时间约束)。需求规格是后续架构设计的基础。
架构设计基于需求规格进行系统概念定义。系统概念定义包括使命定义(系统存在的目的)、愿景陈述(系统的理想状态)、操作概念(系统如何使用)、能力需求(系统应该具备的高层能力)。系统概念为架构设计提供了方向和约束。
架构师提出多个架构方案。没有唯一的正确架构,只有多个各有优劣的可行方案。多个架构方案支持权衡研究,避免过早锁定单一方案。
系统分析对每个架构方案进行定量和定性分析。定量分析使用数学模型和数值计算,如性能模型、可靠性模型、成本模型。定性分析基于专家判断和经验,如检查表、场景分析。系统分析为权衡研究提供了客观依据。
权衡研究比较多个架构方案,选择最优方案。权衡研究方法包括决策矩阵、Pugh矩阵、AHP、成本效益分析等。权衡研究不仅比较方案的整体优劣,还分析方案对不同质量属性的影响,识别权衡点。权衡研究的输出是推荐的架构方案和选择理由。
架构评审与确认是重要的决策点。利益相关者评审推荐的架构方案,确认是否满足需求。架构评审是质量控制点,确保架构在详细设计之前是合理的。
实施阶段将架构转化为实际系统。实现包括编码(软件)、制造(硬件)、组件采购(COTS组件)。实现策略可以是自顶向下、自底向上、或中间相遇。实现过程中需要管理技术债务,坚持质量内建实践。
集成将组件集成为完整系统。集成策略包括大爆炸集成、增量集成、持续集成。集成需要管理接口(接口定义、文档、版本、测试),需要进行集成测试。集成是复杂的过程,往往被低估。
验证确认系统是否正确地实现了需求。验证方法包括审查、仿真、分析、测试。验证在多个层次上进行:单元测试、集成测试、系统测试。验证发现实现问题和集成问题。
确认确认系统是否满足用户需要。确认方法包括用户试用、Beta测试、现场试点、A/B测试。确认发现需求偏差和可用性问题。
系统交付使用后,产生使用反馈,可能触发需求变更。需求变更可能导致架构演进,架构不是一次性的设计,而是随着系统的演化而演化。架构演进需要管理架构变更,评估变更影响,保持架构一致性。
这个图强调了几点重要认识:第一,架构设计是迭代的,不是一次性的活动。需求分析、架构设计、系统分析、权衡研究可能多次循环,才能得到满意的架构方案。第二,架构决策需要权衡,没有完美方案,只有最适合项目约束的方案。第三,验证和确认同等重要,验证确保做对了,确认确保做了正确的事。第四,架构是演化的,随着系统和环境的变化,架构需要适应和演进。
flowchart TD A[架构模式选择] --> B[问题特征] A --> C[质量属性要求] A --> D[团队能力] A --> E[技术约束] B --> B1[功能驱动] B --> B2[数据驱动] B --> B3[事件驱动] B --> B4[分布式] C --> C1[性能优先] C --> C2[可修改性优先] C --> C3[可靠性优先] C --> C4[可扩展性优先] D --> D1[熟悉领域] D --> D2[新技术学习] D --> D3[团队规模] E --> E1[现有技术栈] E --> E2[平台限制] E --> E3[标准要求] B1 --> F[分层架构<br/>管道过滤器] C1 --> F D1 --> F E1 --> F B2 --> G[分层架构<br/>领域驱动设计] C2 --> G D1 --> G E1 --> G B3 --> H[事件驱动<br/>发布订阅] C4 --> H D2 --> H E1 --> H B4 --> I[客户服务器<br/>微服务<br/>发布订阅] C4 --> I D3 --> I E1 --> I F --> J[选择考虑<br/>简单、成熟、易于理解] G --> K[选择考虑<br/>关注点分离、模块化] H --> L[选择考虑<br/>松耦合、异步性] I --> M[选择考虑<br/>分布性、可扩展性、复杂性] J --> N[组合使用<br/>不同层次/部分使用不同模式] K --> N L --> N M --> N
图表讲解:这个流程图展示了如何根据项目情况选择合适的架构模式。架构模式的选择需要综合考虑问题特征、质量属性要求、团队能力和技术约束。
问题特征是首要考虑因素。功能驱动的系统(如业务应用)适合分层架构,分层架构提供了清晰的功能组织。数据驱动的系统(如数据分析系统)适合管道过滤器架构,数据在过滤器之间流动,每个过滤器执行特定的转换。事件驱动的系统(如用户界面、物联网系统)适合事件驱动架构或发布订阅架构,组件通过事件或消息通信,实现松耦合。分布式系统(如大规模Web应用)适合客户服务器架构、微服务架构、发布订阅架构,这些架构支持分布性和可扩展性。
质量属性要求是另一个重要因素。性能优先的系统(如高频交易)可能需要优化的数据结构、缓存策略、并发机制,这些在特定架构模式中更容易实现。可修改性优先的系统(如快速迭代的产品)需要模块化、低耦合的架构,分层架构、领域驱动设计提供了良好的模块化。可靠性优先的系统(如安全关键系统)需要冗余、故障检测、故障恢复机制,某些架构模式更容易支持这些机制。可扩展性优先的系统(如云计算平台)需要水平扩展能力,微服务架构、发布订阅架构天然支持可扩展性。
团队能力是实际约束。如果团队熟悉某些架构模式,使用熟悉模式可以降低学习曲线和风险。如果团队需要学习新技术,需要评估学习成本和时间。团队规模也影响架构模式选择,小团队可能适合简单的架构模式,大团队可以分解为多个小团队,每个团队负责一个微服务。
技术约束限制了架构模式的选择。现有技术栈可能更适合某些架构模式,例如,.NET技术栈更适合分层架构。平台限制(如云平台、移动平台)可能推荐或限制某些架构模式。标准要求(如行业标准、公司标准)可能要求使用特定的架构模式。
图的右侧总结了不同架构模式的选择考虑。分层架构和管道过滤器是简单、成熟、易于理解的模式,适合中小型应用。分层架构强调关注点分离,管道过滤器强调数据流处理。事件驱动和发布订阅架构强调松耦合和异步性,适合需要解耦和并发的系统。客户服务器、微服务、发布订阅架构支持分布性和可扩展性,但引入了分布式复杂性。
架构模式不是排他的,可以组合使用。不同层次可以使用不同模式,例如,应用层使用分层架构,底层使用事件驱动架构。不同部分可以使用不同模式,例如,用户界面部分使用MVC模式,数据处理部分使用管道过滤器。组合使用需要仔细设计接口,确保不同模式之间的协作。
理解架构模式的选择,需要认识到没有万能的模式。选择架构模式需要综合考虑多个因素,根据项目的具体情况做出决策。架构模式的选择还影响后续的设计和实现,选择不当可能带来高昂的修改成本。
flowchart TD A[质量属性分析] --> B[性能] A --> C[可修改性] A --> D[可靠性] A --> E[安全性] A --> F[可扩展性] B --> B1[关注点<br/>响应时间<br/>吞吐量<br/>资源利用率] B --> B2[架构方法<br/>资源调度<br/>并发处理<br/>缓存策略] B --> B3[权衡<br/>性能 vs 成本<br/>性能 vs 可修改性] C --> C1[关注点<br/>模块化<br/>耦合度<br/>组件独立性] C --> C2[架构方法<br/>接口设计<br/>封装<br/>依赖管理] C --> C3[权衡<br/>可修改性 vs 性能<br/>可修改性 vs 复杂度] D --> D1[关注点<br/>可用性<br/>故障率<br/>恢复时间] D --> D2[架构方法<br/>冗余设计<br/>故障检测<br/>故障恢复] D --> D3[权衡<br/>可靠性 vs 成本<br/>可靠性 vs 性能] E --> E1[关注点<br/>机密性<br/>完整性<br/>可用性] E --> E2[架构方法<br/>认证授权<br/>加密<br/>审计] E --> E3[权衡<br/>安全性 vs 易用性<br/>安全性 vs 性能] F --> F1[关注点<br/>水平扩展<br/>负载分布<br/>弹性] F --> F2[架构方法<br/>无状态设计<br/>数据分片<br/>自动化扩展] F --> F3[权衡<br/>可扩展性 vs 成本<br/>可扩展性 vs 一致性] B3 --> G[权衡分析<br/>质量属性相互竞争<br/>需要架构决策平衡] C3 --> G D3 --> G E3 --> G F3 --> G G --> H[ATAM方法<br/>识别质量属性场景<br/>分析架构方法影响<br/>发现权衡点]
图表讲解:这个流程图展示了系统质量属性的分析方法和权衡考虑。质量属性是架构决策的关键驱动因素,不同的质量属性需要不同的架构方法,质量属性之间往往存在权衡关系。
性能关注系统的响应时间、吞吐量和资源利用率。性能的架构方法包括资源调度(如何分配计算资源)、并发处理(如何处理并发请求)、缓存策略(如何减少重复计算)。性能与其他质量属性存在权衡:追求高性能可能增加成本(需要更多或更好的资源),追求高性能可能损害可修改性(性能优化往往使代码更复杂)。性能权衡的例子包括:使用缓存提高性能但增加了一致性挑战,使用并发提高性能但增加了复杂性。
可修改性关注系统适应变化的能力,包括模块化、耦合度、组件独立性。可修改性的架构方法包括接口设计(定义清晰的接口)、封装(隐藏内部实现)、依赖管理(管理组件之间的依赖)。可修改性与其他质量属性存在权衡:追求高可修改性可能损害性能(额外的抽象层增加开销),追求高可修改性可能增加复杂度(更多的抽象和接口)。可修改性权衡的例子包括:使用依赖注入提高可修改性但增加了运行时开销,使用接口抽象提高可修改性但增加了类的数量。
可靠性关注系统的可用性、故障率和恢复时间。可靠性的架构方法包括冗余设计(组件冗余、数据冗余)、故障检测(心跳、监控)、故障恢复(自动故障转移)。可靠性与其他质量属性存在权衡:追求高可靠性可能增加成本(冗余需要额外资源),追求高可靠性可能损害性能(故障检测和恢复的开销)。可靠性权衡的例子包括:使用同步复制提高可靠性但增加了写延迟,使用异步复制提高性能但可能丢失数据。
安全性关注系统的机密性、完整性、可用性。安全性的架构方法包括认证授权(验证身份和权限)、加密(保护数据)、审计(记录安全事件)。安全性与其他质量属性存在权衡:追求高安全性可能损害易用性(额外的认证步骤),追求高安全性可能损害性能(加密解密开销)。安全性权衡的例子包括:使用强加密提高安全性但增加计算开销,使用多因素认证提高安全性但降低易用性。
可扩展性关注系统的水平扩展能力、负载分布和弹性。可扩展性的架构方法包括无状态设计(状态外置)、数据分片(数据分布)、自动化扩展(自动增减资源)。可扩展性与其他质量属性存在权衡:追求高可扩展性可能增加成本(需要支持扩展的基础设施),追求高可扩展性可能损害一致性(分布式一致性困难)。可扩展性权衡的例子包括:使用最终一致性提高可扩展性但牺牲了强一致性,使用微服务提高可扩展性但增加了运维复杂性。
图的右下角强调,质量属性相互竞争,需要架构决策平衡。ATAM(架构权衡分析方法)是分析质量属性权衡的系统性方法。ATAM通过质量属性场景明确需求,通过架构方法分析影响,通过权衡分析识别冲突点。ATAM的目标不是找到最优解(因为不存在),而是做出明智的权衡决策,理解权衡的后果。
理解质量属性的权衡,有助于架构师做出理性的决策。架构决策不是在真空中做出的,而是在具体的质量属性需求约束下做出的。理解权衡关系,可以帮助解释为什么某个架构方案在某些方面表现好,在其他方面表现差。理解权衡关系,还可以帮助预测架构变更的影响——改变某个质量属性可能影响其他质量属性。
六、常见问题解答
Q1:架构设计什么时候开始?什么时候结束?
答:架构设计是贯穿项目全生命周期的活动,不是某个阶段的一次性活动。
架构设计通常在概念阶段开始,当需求和概念基本明确后,就可以开始探索架构方案。早期架构设计是探索性的,尝试多种方案,进行权衡分析。早期架构设计影响需求分析——某些需求可能因为架构限制而无法实现,需要调整需求。
在开发阶段,架构设计进入细化阶段。架构设计从高层架构逐步细化到详细设计,定义组件、接口、交互。这个阶段的架构设计需要与实现活动协调,设计指导实现,实现反馈设计。
在运行维护阶段,架构设计进入演化阶段。系统在实际环境中运行,产生新的需求和问题,架构需要适应和演化。架构演化可能是增量修改(添加新功能、修改现有功能),也可能是重构(调整架构结构)。架构演化需要评估影响,管理变更,保持架构一致性。
架构设计”结束”的标准不是某个时间点,而是架构达到稳定状态。稳定架构的定义是:架构能够满足当前需求,架构变更的频率和规模降低到可接受水平。对于长生命周期的系统,架构可能永远不会完全稳定,持续演化是常态。
架构设计不是一个人的工作,而是团队的活动。架构师主导架构设计,但需要开发人员、测试人员、利益相关者的参与。架构设计需要集体智慧,需要多方评审,需要达成共识。
Q2:如何判断一个架构是好架构?
答:判断架构质量需要综合考虑多个维度,没有单一的标准。
好架构首先应该满足功能需求。架构必须能够实现系统的功能需求,这是基本要求。如果架构不能实现功能需求,无论其他方面多么优秀,都是失败的架构。
好架构应该满足质量属性需求。架构应该在性能、可靠性、安全性、可修改性、可扩展性等质量属性上满足项目要求。但需要注意的是,不同项目对质量属性的要求不同,好架构不是在所有质量属性上都优秀,而是在项目关注的质量属性上满足要求。
好架构应该是可理解的。架构应该足够简单,团队成员能够理解和沟通。复杂的架构难以维护,容易引入缺陷。架构的简单性不是指功能简单,而是指结构清晰、逻辑一致、没有不必要的复杂性。
好架构应该是可演化的。架构应该能够适应需求变化和技术变化,不需要大规模重构。可演化的架构通常具有模块化、低耦合、高内聚的特性,使得部分可以独立变化而不影响整体。
好架构应该是可实现的。架构必须能够在项目约束(时间、成本、技能)下实现。过于理想化的架构无法实现,或者实现成本过高。好架构在理想与现实之间找到平衡。
好架构应该是可验证的。架构应该能够被分析和验证,确保满足关键需求。如果架构无法验证,就无法确保其正确性。可验证性通常需要形式化或半形式化的表示,支持分析和推理。
判断架构质量的具体方法包括:架构评审(专家评审架构)、原型验证(构建原型验证架构)、场景分析(通过场景验证架构)、质量属性分析(定量或定性分析质量属性)。判断架构质量应该尽早进行,在详细设计和实现之前,避免后期返工。
Q3:架构师和开发人员有什么区别?
答:架构师和开发人员是不同的角色,有不同的关注点和责任,但在实践中边界可能模糊。
架构师关注系统的整体结构,开发人员关注组件的内部实现。架构师考虑系统如何分解为组件,组件之间如何交互,组件如何部署。开发人员考虑单个组件如何设计,算法如何实现,代码如何编写。
架构师考虑长期和全局,开发人员考虑短期和局部。架构师考虑系统未来几年的演化,考虑系统如何适应变化。开发人员考虑当前迭代的功能,考虑如何完成分配的任务。
架构师关注权衡,开发人员关注实现。架构师在不同的质量属性之间权衡,在不同的架构方案之间权衡。开发人员关注如何正确高效地实现分配的功能。
架构师需要广泛的知识,开发人员需要深入的知识。架构师需要了解多个技术领域,了解不同的架构模式和方法。开发人员需要在某个技术领域深入,掌握该领域的细节和最佳实践。
架构师需要沟通和协调能力,开发人员需要技术实现能力。架构师需要与利益相关者沟通需求,与开发团队协调设计,与项目经理协调进度。开发人员需要将设计转化为高质量的代码或产品。
在实践中,架构师和开发人员的边界可能模糊。在小团队中,可能没有专职的架构师,开发人员共同承担架构设计责任。在大团队中,可能有多个架构师,分别负责不同的架构层面(应用架构、技术架构、数据架构)。优秀的开发人员可以成长为架构师,架构师也需要一定的开发经验,否则设计可能脱离实际。
架构师和开发人员是互补的角色,需要紧密协作。架构师提供设计方向和约束,开发人员提供实现反馈和细节。架构师和开发人员之间的良好协作是项目成功的关键。
Q4:如何处理架构的演化?架构变化了怎么办?
答:架构演化是常态,需要系统化的方法管理架构变更。
架构演化的驱动因素包括:需求变化(新功能、修改现有功能)、技术变化(新技术出现、旧技术淘汰)、环境变化(运行环境、法规标准变化)、问题修复(架构缺陷、性能问题)。架构演化的目标是在保持架构稳定性的同时,适应必要的变更。
架构演化管理包括以下活动:
变更请求评估:当提出架构变更时,需要评估变更的必要性、影响和成本。变更的必要性考虑变更是否真的需要,是否有替代方案。变更的影响考虑变更影响哪些组件、接口、质量属性。变更的成本考虑实现变更的工作量和风险。变更请求评估决定是否接受变更。
影响分析:对于接受的变更,需要进行详细的影响分析。影响分析识别变更影响的所有架构元素(组件、接口、配置)、相关的文档和测试、相关的开发团队。影响分析还需要评估变更对不同质量属性的影响,可能产生的新风险。影响分析的结果指导变更实施计划。
变更实施计划:基于影响分析,制定变更实施计划。变更实施计划定义变更的范围(哪些部分修改)、变更的步骤(如何修改)、变更的顺序(先后依赖关系)、变更的资源(谁来做)、变更的时间(何时做)。变更实施计划需要与相关团队协商,确保计划的可行性。
架构版本管理:架构变更需要版本管理,类似于代码的版本管理。架构版本包括架构文档、架构模型、架构决策记录(ADR)。架构版本管理需要定义基线(稳定的架构版本)、变更流程(如何从当前版本到新版本)、回滚机制(如果变更失败如何回退)。架构版本管理确保架构演化的可追溯性和可控性。
架构决策记录(ADR):ADR是记录重要架构决策的文档,包括决策的背景、考虑的选项、选择的原因、预期的后果。ADR帮助理解架构为什么是这样,如果问题再次出现,可以回顾之前的决策。ADR还支持架构演化,如果决策的前提变化,可以重新评估决策。
架构合规性检查:架构变更后,需要确保实现符合架构。架构合规性检查包括:代码审查(检查代码是否符合架构设计)、自动化检查(工具检查架构约束)、架构评审(评审架构变更和影响)。架构合规性检查防止架构偏离,即实现逐渐偏离架构设计,导致技术债务累积。
架构演化需要平衡稳定性和适应性。稳定性意味着架构不能频繁变化,否则团队难以跟上。适应性意味着架构需要适应变化,否则架构会过时。平衡的关键是只接受必要的架构变更,确保每次变更都有明确的理由和充分的分析。
Q5:敏捷方法如何与架构设计结合?敏捷是不是不需要架构?
答:敏捷方法不是不需要架构,而是采用不同的架构方法。传统方法倾向于”大设计 upfront”(Big Design Up Front, BDUF),在开发前完成详细的架构设计。敏捷方法倾向于”刚好足够的架构”和”演化架构”。
刚好足够的架构意味着在开发早期只做必要的架构设计,不过度设计。刚好足够的架构满足以下条件:支持当前和近期的开发需求,为后续演化留下空间,不过度限制实现选择。刚好足够的架构不是没有架构,而是不过度设计的架构。
演化架构意味着架构随着系统的演化而演化,而不是在早期固定下来。演化架构假设早期无法完全理解问题和解决方案,随着系统的实现和使用,理解会加深,架构需要适应新的理解。演化架构需要架构具有可演化性(模块化、低耦合),需要架构能够适应变化而不崩溃。
敏捷实践支持架构设计和演化:
迭代0(Sprint 0):许多敏捷团队在第一个迭代(称为迭代0或Sprint 0)进行架构准备工作。迭代0通常不是交付用户价值,而是为开发做好准备,包括设置开发环境、搭建架构骨架、定义接口约定。迭代0的架构工作是”刚好足够的架构”,支持后续迭代开发。
Spikes(技术探索):Spikes是时间盒的技术探索活动,用于解决技术不确定性。Spikes可能包括架构调研、技术验证、原型开发。Spikes的结果帮助团队做出架构决策,指导后续开发。Spikes是敏捷中的架构探索活动。
持续重构:重构是改善代码结构而不改变外部行为。持续重构意味着重构是持续的活动,而不是一次性的大重构。持续重构保持架构的健康,防止技术债务累积。持续重构需要自动化测试支持,确保重构不破坏功能。
架构主人(Architect Owner):在敏捷团队中,可能有架构主人角色,负责架构设计和协调。架构主人不是传统的架构师(远离开发团队),而是开发团队的一部分,与团队一起工作。架构主人提供架构方向,同时参与实现,确保架构的可行性。
架构评审:敏捷团队可以定期进行架构评审,审查架构的健康和演化。架构评审可能包括:代码审查(架构合规性)、技术债务评估(识别和优先级排序技术债务)、架构回顾(回顾架构决策的有效性)。架构评审支持架构的持续改进。
敏捷与架构不是对立的,而是互补的。敏捷提供了适应性和快速反馈,架构提供了结构和方向。结合敏捷和架构,可以在快速变化的同时保持系统的完整性。
七、总结
本文系统介绍了系统架构设计与实现的方法和实践。架构设计是系统开发的核心活动,决定了系统的整体质量和可演化性。
系统开发始于问题识别和机会分析,需要明确”为什么要开发这个系统”。系统概念定义包括使命、愿景、操作概念、能力需求、约束条件。需求工程包括需求获取、分析、规格化、验证、管理,是架构设计的基础。
架构设计遵循一些基本原则,如关注点分离、高内聚低耦合、抽象封装、单一职责、开放封闭、依赖倒置等。架构视图从不同角度描述系统,4+1视图模型是经典的视图框架。架构模式是经过验证的解决方案模板,如分层架构、管道过滤器、客户服务器、事件驱动、微服务等。
系统分析和权衡研究为架构决策提供依据。定量分析方法包括性能模型、可靠性模型、安全性模型、成本模型。定性分析方法包括检查表、场景分析、权衡分析。权衡研究方法包括决策矩阵、Pugh矩阵、AHP、成本效益分析等。ATAM是关注质量属性权衡的架构评估方法。
系统实现将设计转化为实际系统,需要考虑实现策略、并行实现、组件采购与自制、技术债务管理、质量内建。系统集成将组件集成为完整系统,需要考虑集成策略、持续集成、接口管理、集成测试。系统验证确认系统是否正确地实现了需求,系统确认确认系统是否满足用户需要。
架构设计不是一次性的活动,而是贯穿项目全生命周期的活动。架构演化是常态,需要系统化的方法管理架构变更。敏捷方法与架构设计可以结合,采用”刚好足够的架构”和”演化架构”的方法。
理解系统架构设计与实现,有助于我们设计出高质量的、可演化的系统,满足用户需求,适应变化环境。
八、核心概念总结
| 概念名称 | 定义 | 应用场景 | 注意事项 |
|---|---|---|---|
| 系统架构 | 系统的基本组织结构,包括组件、关系、原则 | 系统设计、技术决策 | 高层抽象、影响持久 |
| 架构视图 | 从特定角度描述系统的表示 | 沟通、文档 | 多视图组合 |
| 4+1视图 | 逻辑、进程、物理、开发、用例视图 | 架构描述 | 经典框架 |
| 架构模式 | 经过验证的架构解决方案模板 | 设计重用 | 不是具体实现 |
| 分层架构 | 将系统组织为多个层次的架构模式 | 企业应用 | 关注点分离 |
| 微服务架构 | 将系统组织为小型独立服务的架构 | 大型分布式系统 | 分布式复杂性 |
| 质量属性 | 系统的非功能特性 | 架构评估 | 相互权衡 |
| 权衡研究 | 比较多个方案的分析过程 | 架构决策 | 多准则分析 |
| ATAM | 架构权衡分析方法 | 架构评估 | 关注质量属性 |
| 持续集成 | 频繁集成、自动构建测试的实践 | 敏捷开发 | 快速反馈 |
| 技术债务 | 为了速度而牺牲的质量 | 迭代开发 | 需要管理 |
| 架构演化 | 架构随系统变化的适应过程 | 长生命周期系统 | 需要管理 |
九、下篇预告
下一篇我们将深入探讨系统工程管理与实践,带你了解技术规划与项目评估、需求管理与配置管理、风险管理与质量管理、决策管理过程,以及系统维护与升级策略。