背书答案
UML
依赖:A - - - - > B 关联:A ─────> B 聚合:A ◇──── B 组合:A ◆──── B 泛化:A ─────▷ B 实现:A - - - -▷ B
Object-Oriented Design Principles
- 单一职责原则 SRP:一个类只负责一个功能领域中的相应职责,一个类不应该承担太多变化原因
- 开闭原则 OCP:软件实体应当对扩展开放、对修改关闭,即尽量在不修改原有代码的基础上扩展系统行为
- 里氏代换原则 LSP:所有引用基类对象的地方都应该能够透明地使用其子类对象,子类替换父类后系统行为不应被破坏
- 依赖倒转原则 DIP:抽象不应该依赖于细节,细节应该依赖于抽象,要针对接口编程,不要针对实现编程
- 接口隔离原则 ISP:客户端不应该依赖它不需要的接口,应把大接口拆成更小、更专门的接口
- 合成复用原则 CRP:复用时优先使用对象组合 / 聚合,而不是继承;组合是黑盒复用,继承是白盒复用
- 迪米特法则 LoD:一个软件实体应尽可能少地与其他实体发生相互作用,如果两个类不必直接通信,就通过第三者间接交互
目标是开闭原则;指导原则是迪米特法则;基础是单一职责原则和可变性封装原则;实现手段包括依赖倒转原则、合成复用原则、里氏代换原则和接口隔离原则
Design Pattern
设计模式是一套被反复使用、多数人知晓、经过分类编目的代码设计经验总结。它用于提高代码复用性、可理解性和可靠性。一个设计模式通常包括模式名称、问题、解决方案和效果。按目的可分为创建型、结构型和行为型;按范围可分为类模式和对象模式
Simple Factory Pattern
简单工厂模式定义一个专门的工厂类,根据传入参数创建不同具体产品对象。它的核心角色包括 Factory、Product、ConcreteProduct。客户端只需要知道参数,不需要知道具体产品类名和创建细节。优点是分离对象创建和业务处理,客户端使用简单;缺点是工厂类职责过重,新增产品通常要修改工厂判断逻辑,违背开闭原则。简单工厂不是 GoF 23 种设计模式之一

Factory Method Pattern
工厂方法模式定义创建产品对象的工厂接口,把具体实例化延迟到工厂子类。它的核心角色包括 Product、ConcreteProduct、Factory、ConcreteFactory。一个具体工厂通常对应一种具体产品;新增产品时新增具体产品和具体工厂。优点是符合开闭原则,隐藏具体产品创建细节;缺点是类数量增加,抽象层增加理解难度。工厂方法针对一个产品等级结构

Abstract Factory Pattern
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定具体类。它的核心角色包括 AbstractFactory、ConcreteFactory、AbstractProduct、ConcreteProduct。抽象工厂面向产品族,一个具体工厂负责创建同一产品族中的多个产品。优点是隔离具体类生成、方便更换产品族、保证客户端使用同一产品族对象;缺点是新增产品族容易,新增产品等级结构困难,这叫开闭原则的倾斜性


Builder Pattern
建造者模式将复杂对象的构建过程与表示分离,使同样的构建过程可以创建不同表示。它的核心角色包括 Builder、ConcreteBuilder、Director、Product。Director 控制构建顺序,Builder 负责逐步创建产品部件,客户端不需要关心内部组装细节。优点是产品和创建过程解耦,可精细控制创建过程;缺点是产品差异很大时不适合,内部变化复杂时具体建造者会很多。建造者返回一个组装好的完整产品

Prototype Pattern
原型模式用原型实例指定创建对象的种类,并通过复制原型创建新对象。它的核心角色包括 Prototype、ConcretePrototype、Client。适用于创建对象成本大、对象状态组合少、需要复制粘贴或保存状态的情况。优点是简化对象创建、提高创建效率、可动态增减原型对象;缺点是每个类需要实现克隆方法,深克隆实现复杂。浅克隆只复制对象本身,内部引用对象仍共享;深克隆会复制内部引用对象

Adapter Pattern
适配器模式将一个接口转换成客户端期望的另一个接口,使接口不兼容的类可以协同工作。它的核心角色包括 Target、Adapter、Adaptee、Client。适配器把客户端请求转换成对适配者方法的调用,改变的是对外接口,不是原有类本身。类适配器使用继承,对象适配器使用组合;对象适配器通常更灵活。它适用于复用已有类但接口不符合系统需要的情况


Composite Pattern
组合模式将对象组合成树形结构表示整体-部分层次,使客户端一致处理单个对象和组合对象。它的核心角色包括 Component、Leaf、Composite、Client。Composite 可以包含 Leaf,也可以包含其他 Composite,形成递归结构。适用于文件目录、XML、GUI 组件等树形结构。透明组合把 add/remove/getChild 放在 Component 中,强调一致性;安全组合只放在 Composite 中,强调类型安全

Bridge Pattern
桥接模式将抽象部分与实现部分分离,使二者可以独立变化。它的核心角色包括 Abstraction、RefinedAbstraction、Implementor、ConcreteImplementor。桥接模式把继承关系转换为关联关系,用组合 / 聚合替代多层继承。它适用于存在两个独立变化维度、可能产生类爆炸、不希望抽象和实现静态绑定的场景。桥接通常用于系统初步设计;适配器常用于已有系统接口不兼容后的补救

Decorator Pattern
装饰模式动态地给一个对象增加额外职责,提供比继承更灵活的功能扩展方式。它的核心角色包括 Component、ConcreteComponent、Decorator、ConcreteDecorator。装饰者和被装饰者实现同一接口,装饰者内部持有 Component 引用,并在调用前后添加行为。它适用于动态增加或撤销功能、功能组合很多、不想用继承扩展对象的场景。装饰模式扩展对象职责;代理模式控制对象访问;适配器模式转换接口

Facade Pattern
外观模式为子系统中的一组接口提供统一的高层接口,使子系统更容易使用。它的核心角色包括 Facade、SubSystem、Client。客户端只与外观对象交互,复杂子系统调用由外观统一处理。优点是屏蔽子系统复杂性、降低耦合、体现迪米特法则;缺点是不能完全限制客户端直接访问子系统,没有抽象外观时增加新子系统可能违背开闭原则。外观模式负责简化访问,不负责给子系统增加新行为

Flyweight Pattern
享元模式运用共享技术有效支持大量细粒度对象的复用。它的核心角色包括 Flyweight、ConcreteFlyweight、UnsharedConcreteFlyweight、FlyweightFactory。享元模式共享内部状态 intrinsic state,外部状态 extrinsic state 由客户端保存并传入。适用于大量相同或相似对象、内存消耗大、对象大部分状态可外部化的场景。优点是减少内存中对象数量,缺点是必须区分内部状态和外部状态,系统逻辑更复杂

Proxy Pattern
代理模式为某个对象提供代理,并由代理对象控制对真实对象的访问。它的核心角色包括 Subject、Proxy、RealSubject、Client。代理和真实对象实现同一接口,代理内部持有真实对象引用,并在访问前后执行额外操作。常见类型包括远程代理、虚拟代理、保护代理、缓存代理。它适用于远程访问、延迟加载、权限控制、缓存、防火墙、智能引用等场景

Strategy
策略模式定义一族算法,分别封装每个算法,并使它们可以相互替换。它的核心角色包括 Context、Strategy、ConcreteStrategy。Context 通过组合持有策略对象,算法可以独立于客户端变化。适用于一组算法、行为可替换、大量 if-else/switch、运行时切换行为的场景。优点是封装变化、替代继承、消除条件语句、符合开闭原则;缺点是客户端需要知道不同策略,策略类数量增加

State
状态模式允许对象在内部状态改变时改变其行为,对象看起来像修改了它的类。它的核心角色包括 Context、State、ConcreteState。状态模式把不同状态下的行为和转换规则封装到不同状态类中。适用于对象行为依赖状态、状态经常切换、大量与状态有关的条件语句的场景。状态模式关注同一对象不同状态下行为不同;策略模式关注算法族可替换

Command
命令模式将一个请求封装为对象,使请求发送者和接收者解耦。它的核心角色包括 Command、ConcreteCommand、Invoker、Receiver、Client。命令对象可以被存储、传递、排队、记录日志,并支持撤销 / 重做。它适用于命令队列、日志、Undo/Redo、宏命令等场景。宏命令是命令模式和组合模式联用

Observer
观察者模式定义对象间一对多依赖关系,使一个对象状态变化时,所有依赖对象得到通知并自动更新。它的核心角色包括 Subject、ConcreteSubject、Observer、ConcreteObserver。Subject 维护观察者列表,通过 attach/detach/notify 注册、移除和通知观察者。适用于状态变化通知多个对象、发布-订阅、事件监听、Model 改变 View 自动更新等场景

Mediator
中介者模式用一个中介对象封装一系列对象交互,避免对象之间显式相互引用。它的核心角色包括 Mediator、ConcreteMediator、Colleague、ConcreteColleague。它把多对多复杂交互改成同事对象与中介者之间的一对多关系。优点是简化对象交互、同事类解耦;缺点是具体中介者可能过于复杂。中介者模式体现迪米特法则,MVC 中的 Controller 常可理解为中介者

Template
模板方法模式在父类中定义算法骨架,把某些步骤延迟到子类实现。它的核心角色包括 AbstractClass、ConcreteClass。模板方法负责组织整体流程,基本方法表示算法步骤,钩子方法提供可选扩展点。适用于算法流程固定、部分步骤变化、公共行为提取到父类、框架控制子类扩展的场景。它体现好莱坞原则:Don’t call us, we’ll call you

质量属性场景
Availability
Interoperability
Modifiability
Performance
Security
Testability
Usability
| 质量属性 | 刺激源 | 刺激 | 工件 | 环境 | 响应 | 响应度量 | 对应 tactic / 设计理由 |
|---|---|---|---|---|---|---|---|
| Availability | Heartbeat 监视器 | 服务器无响应 | 进程 | 正常操作 | 通知操作者,并继续运行 | 没有停机时间 | heartbeat 用于 detect faults;process monitor / failover 用于自动恢复或继续服务 |
| Interoperability | 本车车辆信息系统 | 发送当前位置 | 路况监控系统 | 系统在运行前已知 | 路况监控系统将当前位置与其他信息结合,叠加到 Google Maps 上,并进行广播 | 我们的信息在 99.9% 的时间被正确包含 | discovery service 用于 locate;orchestrate / tailor interface 用于管理多个系统接口和响应处理 |
| Modifiability | 开发者 | 希望修改 UI | 代码 | 设计时 | 修改完成并进行单元测试 | 在 3 小时内完成 | encapsulate / use an intermediary 降低 UI 与业务逻辑耦合;defer binding 让 UI 变化更局部 |
| Performance | 用户 | 发起事务 | 系统 | 正常操作 | 事务被处理 | 平均延迟为 2 秒 | prioritize events / reduce overhead 控制资源需求;introduce concurrency / caching 管理资源 |
| Security | 来自远程地点、心怀不满的员工 | 尝试修改薪酬标准 | 系统内数据 | 正常操作 | 系统维护审计追踪 | 正确数据在 1 天内恢复,并识别篡改来源 | authenticate / authorize actors 控制访问;verify message integrity / audit log 追踪篡改 |
| Testability | 单元测试者 | 代码单元完成 | 代码单元 | 开发时 | 结果被捕获 | 3 小时内达到 85% 的路径覆盖 | specialized interfaces 控制和观察状态;record/playback 记录测试过程和结果 |
| Usability | 用户 | 下载新应用 | 系统 | 运行时 | 用户高效地使用应用 | 经过 2 分钟试用 / 探索即可达到 | maintain task model / user model 提供引导;cancel、undo、feedback 降低误操作成本 |
Architecture vs Design vs Structure
Architecture 和 design 的关系:
- Architecture 是 software design 的一部分
- architecture 关注的是 high-level design,是一组对系统整体结构和关键质量属性有重要影响的 design decisions
Architecture 和 structure 的关系:
- Structure 更强调把系统分解为 components、modules、subsystems
- Architecture 包含 structure / organization,但比简单分解更进一步:它定义 component interfaces,即组件能做什么;定义 component communications and dependencies,即组件如何通信、如何依赖;还定义 component responsibilities,即当请求某个组件时,它具体应该完成什么
What Does a Software Architect Do
| 英文 | 中文 | 解释 |
|---|---|---|
| liaison | 沟通协调 / 联络 | 在客户、技术团队和业务 / 需求分析人员之间;与管理层或市场人员之间 |
| software engineering | 软件工程 | 软件工程最佳实践 |
| technical knowledge | 技术知识 | 对技术领域的深入理解 |
| risk management | 风险管理 | 与设计、技术选择相关的风险;以及其他风险 |
速记:架构师 = 对外联络,对内按工程做,用技术判断,管架构风险
Where Do Architectures Come From
| 英文 | 中文 | 对架构的影响 |
|---|---|---|
| NFRs | 非功能需求 | 描述系统“做得多好”,如性能、可用性、安全性、易用性,通常直接驱动架构决策 |
| ASRs | 架构显著需求 | 对架构有重大影响的需求,是架构设计最直接的驱动因素 |
| QRs | 质量需求 / 质量属性需求 | 具体化质量属性要求,常用质量属性场景表达 |
| stakeholders | 利益相关者 | 提供业务目标、关注点、约束和质量属性优先级 |
| organizations | 组织因素 | 团队结构、开发流程、预算、进度、治理方式会限制或塑造架构 |
| technical environments | 技术环境 | 平台、框架、基础设施、已有系统、部署环境和技术约束会影响架构选择 |
速背
- 需求类:NFRs、ASRs、QRs
- 人:stakeholders
- 组织:organizations
- 技术环境:technical environments
Generic Design Strategy
| 策略 | 含义 | 架构例子 |
|---|---|---|
| Decomposition | 拆分复杂系统 | 电商拆成用户、订单、库存、支付服务 |
| Abstraction | 忽略细节,保留关键接口 | 用 Repository 接口隐藏数据库 |
| Stepwise: Divide and Conquer | 分而治之 | 编译器拆成词法、语法、语义、代码生成 |
| Generate and Test | 生成候选方案并分析 | 比较 active redundancy 和 passive redundancy |
| Iteration :Incremental Refinement | 多轮迭代细化 | ADD 每轮处理一组 drivers |
| Reusable Elements | 复用已有模式、框架、组件 | 使用 MVC、Spring、消息队列 |
记忆:用一个电商系统串起来记
- Decomposition 先把电商系统拆成:用户、商品、订单、库存、支付、物流
- Abstraction 不让订单模块直接知道数据库细节,而是通过:OrderRepository 接口访问数据
- **Stepwise / Divide and Conquer **下单流程太复杂,就分步处理:创建订单 → 锁库存 → 支付 → 发货 → 通知
- Generate and Test 为了提高可用性,提出多个方案,再分析比较
- Iteration / Incremental Refinement 第一轮先设计订单主流程,第二轮补异常处理,第三轮优化性能:
- **Reusable Elements **不要自己从零写所有东西,复用:MVC、Spring Boot、Redis、Kafka、OAuth、设计模式
| 策略 | 在 ADD 中如何体现 |
|---|---|
| Decomposition | Step 3 选择元素并逐步分解 |
| Abstraction | 用模块、组件、接口抽象隐藏细节 |
| Divide and Conquer | Step 2 每次选择一组 drivers,拆成可处理的子问题 |
| Generate and Test | 设计决策是 hypothesis,Step 7 分析并修正 |
| Iteration | ADD 通过多轮迭代逐步完善架构 |
| Reuse | Step 4 使用参考架构、模式、战术、框架 |
对应往年题:
- 2017/2019/2022:What are generic design strategies applied in designing software? Give a concise working example with software architecture for each strategy.
Why should a software architecture be documented using different views? Give 4 example views
- 不同视图支持不同目标和用途,服务不同利益相关者
- 不同视图突出不同系统元素和关系
- 不同视图也会以不同维度暴露质量属性问题
复习时可以把 Module Views、C&C Views、Allocation Views、Quality Views 放在一起比较。前三个主要回答“系统结构是什么”,Quality Views 主要回答“为了分析某个质量属性,需要把哪些相关结构集中起来看”。
| 类别 | 回答问题 | Elements | Relations | 典型 views |
|---|---|---|---|---|
| Module Views | 代码和实现单元如何组织 | modules | is part of、depends on、is a | decomposition、uses、generalization、layered、domain、data model |
| C&C Views | 系统运行时组件如何交互 | components、connectors | attachments、interface delegation | pipe-and-filter、client-server、peer-to-peer、SOA、publish-subscribe、shared-data |
| Allocation Views | 软件元素如何映射到环境 | software elements、environmental elements | allocated to | deployment、installation、work assignment |
| Quality Views | 为分析某个质量属性,应集中查看哪些相关结构 | 来自 module、C&C、allocation views 中与某个质量属性相关的元素 | 取决于被抽取的基础视图 | security view、performance view、reliability view、communications view |
Quality view 不是从零创造新元素,而是从 module、C&C、allocation views 中抽取与某个质量属性相关的元素,重新组织成面向质量属性分析的视图。
例子:
- Security view:认证、授权、敏感数据、信任边界。
- Performance view:请求路径、队列、缓存、瓶颈、延迟。
- Reliability view:冗余、故障检测、切换、恢复。
- Communications view:通信链路、协议、QoS。
连线题速记:
implementation units -> Module
runtime behavior and interactions -> C&C
non-software environment -> Allocation
中文速记:
实现单元怎么组织 -> Module Views
运行时组件怎么交互 -> C&C Views
软件元素如何映射到非软件环境 -> Allocation Views
分析某个质量属性需要集中看哪些结构 -> Quality Views
Architecture Documentation Package
架构文档包 = views + information beyond views。
Information beyond views 包括: 口诀:路法概映理目
| 英文 | 中文 | 作用 |
|---|---|---|
| Documentation Roadmap | 文档路线图 | 告诉读者文档有什么、在哪里找 |
| How a View Is Documented | 视图文档化说明 | 说明视图写法标准和符号约定 |
| System Overview | 系统概览 | 简要说明系统功能、用户、上下文、关键约束 |
| Mapping Between Views | 视图之间的映射 | 说明不同视图中的元素如何对应 |
| Rationale | 设计理由 / 决策依据 | 记录适用于多个 view 的架构决策,以及导致这些决策的背景、组织约束、重大需求和基础架构模式选择 |
| Directory | 参考材料目录 | 帮助读者快速找到更多信息,包括术语索引、术语表和缩略语表 |
主录境变理
| 英文 | 中文 | 作用 |
|---|---|---|
| Primary Presentation | 主要表示 / 主图 | 主图或主表,展示主要元素和关系,必须有图例 |
| Element Catalog | 元素目录 | 解释元素、关系、接口、行为和属性 |
| Context Diagram | 上下文图 | 说明该 view 的边界和外部环境 |
| Variability Guide | 可变性指南 | 说明哪些地方允许变化以及如何变化 |
| Rationale | 设计理由 / 决策理由 | 说明为什么这样设计 |
4+1 View Model
Kruchten 的 4+1 视图模型包括四个结构视图和一个场景视图。
| View | 中文 | 关注点 |
|---|---|---|
| Logical View | 逻辑视图 | 功能需求如何由主要抽象、类、对象、子系统实现 |
| Process View | 进程视图 | 并发、进程、线程、通信、同步、运行时行为 |
| Physical View | 物理视图 | 软件如何部署到硬件节点、网络和物理环境 |
| Development View | 开发视图 | 软件在开发环境中的组织,如模块、库、包、团队分工 |
| Architecture use cases/Scenarios | 场景 / 架构用例 | 捕获架构需求,并验证和串联其他四个视图 |

对应往年题:
- 2017:Describe 4+1 view.
- 2019:介绍 4+1 视图并画图。
ADD3.0
ADD = Attribute-Driven Design。它是一种以架构驱动因素为输入、通过迭代做架构决策的方法
- Step1 Review Inputs
- 确保本轮设计输入可用且正确,包括 Design Purpose、Primary functionality、Quality attribute scenarios、Architectural constraints、Concerns、Existing architecture design,并确认 drivers 及其优先级
- Step2 Establish the Iteration Goal by Selecting Drivers
- 选择本轮要处理的 drivers,建立大小合适的迭代目标,可以解决一个重要 driver,也可以满足一组相关 drivers
- Step3 Choose One or More Elements of the System to Refine
- 选择要细化的系统元素,refinement 可以是分解为更细粒度元素、组合为更粗粒度元素,或改进之前已识别的元素
- Step4 Choose One or more Design Concepts that Satisfy the Selected Drivers
- 先识别候选 design concepts,再选择能满足本轮 drivers 的概念,例如 reference architectures、deployment patterns、architectural/design patterns、tactics、frameworks
- Step5 Instantiate Architectural Elements,Allocate Responsibilities,and Define Interfaces
- 将选定的 design concepts 实例化为具体架构元素,为元素分配职责,并定义元素之间的接口
- Step 6 Sketch Views and Record Design Decisions
- 草拟相关 views 并记录设计决策、理由、元素职责和接口,这些草图是架构的初始文档
- Step7 Perform Analysis of Current Design and Review Iteration Goal and Achievement of Design Purpose
- 分析当前设计,审查迭代目标和设计目的是否达成,并决定是否需要更多迭代(回到step2)
Design Process Termination Criteria
- 设计过程会跨越多次迭代持续进行,直到至少满足下面三种其中之一
- 已经为所有驱动性的架构需求做出设计决策,即达到设计目标
- 最重要的技术风险已经得到缓解
- 分配给架构设计的时间或预算被耗尽
记忆:先看输入,定目标;选对象,挑方案;再落地,写文档;最后评估 终止:做完了、风险稳了、钱/时间没了
- Design of a greenfield system for a mature domain
- 适用于 well-known domains,例如 desktop、mobile、web enterprise apps、microservices
- Initial iteration goal:establish overall system structure,选择 reference architectures、patterns、frameworks,并优先考虑 non-functional constraints 和 quality attributes
- Next iteration goal:identify structures for primary functionality,把 use cases 分配给 elements,分解 reference architecture elements,并规划 team assignments
- Subsequent iterations:refine structures for remaining drivers,使用 tactics、patterns、components 和 best practices,例如 modularity、low coupling
- Roadmap benefits:指导初始设计,帮助早期估算,用已知组件降低风险,并从一开始支持 quality goals
- Design of a greenfield system for a novel domain
- 适用于 less established infrastructure and knowledge base 的新领域
- Start without reference architecture:没有现成模型或可复用组件,设计需要从 first principles 开始
- Use prototyping and general concepts:用 patterns、tactics 和 quality attribute-focused prototypes 指导设计
- Address emerging challenges:重点关注 performance、scalability、security,并保持 flexible iteration goals
- Design for making changes to an existing system (Brownfield)
- Brownfield architecture design 常由 maintenance、refactoring 或 resolving quality issues 驱动
- Understand existing architecture first:先识别系统元素及其 interactions,再进行 decomposition 或 iteration planning
- Design iterations post-assessment:理解现有架构后,ADD 步骤类似 greenfield design,但以增量方式处理新的 drivers
- Design to replace a legacy application
- Legacy tech and technical debt:旧系统可能依赖 obsolete technology,或存在难以管理的 technical debt
- Use the Strangler Fig Pattern:引入 proxy,把调用路由到 legacy systems,同时逐步替换 components
- Iterative replacement:每轮 ADD 的设计目标针对要迁移的 specific services or components
Design concepts
| 类别 | 说明 |
|---|---|
| Reference Architectures | 领域化蓝图,比 architecture style 更具体 |
| Deployment Patterns | 物理部署组织方式,如 3-tier、cluster、failover |
| Patterns | 反复出现设计问题的可复用方案 |
| Tactics | 影响质量属性响应的细粒度设计决策 |
| Externally Developed Components | 外部组件和框架,如 Spring、Hibernate |
对应往年题:
- 2018/2025:描述 ADD / ADD 3.0 过程。
- 2021:架构一般设计策略是什么?以 ADD 为例说明。
- 2025:ADD 3.0 过程。