五大架构风格总结
综合整理自: 软件设计师/软件架构设计师/软件架构风格/数据流风格、软件设计师/软件架构设计师/软件架构风格/调用返回风格、软件设计师/软件架构设计师/软件架构风格/独立构件风格、软件设计师/软件架构设计师/软件架构风格/虚拟机风格、软件设计师/软件架构设计师/软件架构风格/仓库风格
一、总览
架构风格定义了系统结构的规则,包括构件类型、连接方式和约束。考试中常以案例分析题出现,要求识别风格、分析优缺点、选择合适风格。
| # | 风格 | 核心思想 | 一句话记忆 |
|---|---|---|---|
| 1 | 数据流风格 | 数据驱动,前一步输出是后一步输入 | 数据像水一样流过管道 |
| 2 | 调用/返回风格 | 控制流驱动,函数调用并返回 | A 调用 B,B 返回结果 |
| 3 | 独立构件风格 | 事件驱动,构件间松耦合 | 发布事件,谁关心谁处理 |
| 4 | 虚拟机风格 | 抽象执行环境,解释执行 | 在虚拟环境里跑自定义逻辑 |
| 5 | 仓库风格 | 以数据为中心,构件围绕共享数据协作 | 所有人围着一块黑板读写 |
二、各风格详解
1. 数据流风格
核心机制: 数据 → 处理1 → 处理2 → ... → 处理N → 输出
子风格:
- 批处理: 数据按批次整体处理,前一步全部完成后才进入下一步,无用户交互
- 管道-过滤器: 数据流式传输,每个过滤器独立处理数据,弱用户交互
优点:
- 松耦合(高内聚低耦合)
- 良好的重用性 / 可维护性 / 可扩展性
- 支持并行处理
- 信息隐蔽性好
缺点:
- 交互性较差
- 复杂性较高
- 性能较差(每个过滤器都需解析和合成数据)
典型应用: 传统编译器(词法→语法→语义→代码生成)、ETL 数据处理、网络报文处理、图像处理流水线
2. 调用/返回风格
核心机制: 主函数 → 子函数 → 返回结果
子风格:
- 主程序/子程序: 面向过程,自顶向下调用
- 面向对象: 通过对象方法调用实现交互
- 分层结构: 层与层之间单向方法调用(如表现层→业务层→持久层)
优点:
- 良好的重用性(接口不变即可复用)
- 可维护性好,控制流清晰
- 可扩展性好,支持递增设计
缺点:
- 并非所有系统都适合分层
- 难以找到合适的层次抽象方法
- 层间耦合度高的系统难以实现
典型应用: 传统单体应用、分层架构、客户端-服务器架构
3. 独立构件风格
核心机制: 事件源 → 发布事件 → 事件管理器 → 分发 → 事件处理器
子风格:
- 进程通信: 通过 RPC、消息队列等通信
- 事件驱动(隐式调用): 通过事件发布/订阅通信
优点:
- 松耦合(构件间不直接依赖)
- 可扩展性强
- 可复用性好
缺点:
- 控制流程难以预测
- 调试困难
- 数据一致性问题
- 依赖上下文,难以推理
典型应用: 事件驱动架构、微服务间通信、消息驱动系统
4. 虚拟机风格
核心机制: 输入 → 虚拟机(解释器) → 执行 → 输出
子风格:
- 解释器: 解析执行自定义语言或脚本
- 核心组成: 被解释程序、解释器引擎、状态存储、数据存储
- 规则系统: 在解释器基础上增加规则库,根据规则自动推理和执行
- 核心组成: 规则集(知识库)、事实集、规则解释器、工作内存、选择机制
子风格对比:
| 项目 | 解释器 | 规则系统 |
|---|---|---|
| 本质 | 执行程序 | 执行规则 |
| 数据来源 | 输入程序 | 规则库 + 数据 |
| 智能性 | 较低 | 较高 |
| 复杂度 | 中等 | 高 |
优点:
- 灵活应对自定义场景
- 可动态修改业务逻辑无需重新部署
缺点:
- 复杂度较高
- 性能相对较低
典型应用: 编程语言解释器、DSL(领域特定语言)、规则引擎(如 Drools)、专家系统、决策支持系统、工作流引擎
5. 仓库风格(以数据为中心)
核心机制: 构件围绕共享数据仓库进行读写,不直接通信
子风格:
- 数据库系统: 数据集中管理
- 黑板系统: 多模块协作逐步求解问题
- 适用于: 语音识别、图像处理、知识推理
- 超文本系统: 数据网络结构
优点:
- 可扩展性强
- 可复用性高
- 适合复杂问题求解(黑板系统)
缺点:
- 控制复杂
- 难以保证执行顺序
- 开发困难
典型应用: 数据共享系统、协同编辑系统、专家系统(黑板架构)
三、五大风格横向对比
3.1 核心维度对比
| 维度 | 数据流 | 调用/返回 | 独立构件 | 虚拟机 | 仓库 |
|---|---|---|---|---|---|
| 驱动方式 | 数据驱动 | 控制流驱动 | 事件驱动 | 规则/程序驱动 | 数据共享驱动 |
| 耦合度 | 松耦合 | 较紧耦合 | 松耦合 | 中等 | 中等 |
| 交互性 | 差 | 好 | 中等 | 中等 | 中等 |
| 可扩展性 | 好 | 好 | 好 | 好 | 好 |
| 可维护性 | 好 | 好 | 中等 | 中等 | 中等 |
| 控制流 | 顺序 | 明确 | 难预测 | 由规则决定 | 难预测 |
| 调试难度 | 低 | 低 | 高 | 中等 | 高 |
| 性能 | 较差 | 好 | 中等 | 较差 | 中等 |
| 并行支持 | 好 | 差 | 好 | 差 | 中等 |
3.2 构件关系对比
| 风格 | 构件关系 | 通信方式 |
|---|---|---|
| 数据流 | 前后顺序 | 管道/数据流 |
| 调用/返回 | 调用者→被调用者 | 函数调用 |
| 独立构件 | 无直接关系 | 事件/消息 |
| 虚拟机 | 解释器→被解释程序 | 解释执行 |
| 仓库 | 围绕共享数据 | 读写共享存储 |
3.3 独立构件 vs 调用/返回(高频考点)
| 项目 | 独立构件风格 | 调用返回风格 |
|---|---|---|
| 交互方式 | 事件驱动 | 函数调用 |
| 构件关系 | 不直接交互 | 直接调用 |
| 耦合性 | 松耦合 | 紧耦合 |
| 控制方式 | 分散 | 集中 |
四、快速判断方法
考试中遇到架构风格识别题,按以下顺序判断:
- 看数据是否流动 → 数据流风格(批处理 / 管道-过滤器)
- 看是否函数调用 → 调用/返回风格(主子程序 / OO / 分层)
- 看构件是否独立运行、通过事件通信 → 独立构件风格(事件驱动)
- 看是否有解释层 / 规则引擎 → 虚拟机风格(解释器 / 规则系统)
- 看是否围绕共享数据 → 仓库风格(数据库 / 黑板 / 超文本)
五、记忆口诀
数(数据流)调(调用返回)独(独立构件)虚(虚拟机)仓(仓库)
- 数据流 → 水管流水
- 调用返回 → 打电话(你问我答)
- 独立构件 → 广播电台(发信号,谁爱听谁听)
- 虚拟机 → 翻译官(中间层解释执行)
- 仓库 → 图书馆(大家围着书架读写)
六、性能扩展方式
架构风格决定了系统的扩展方向和扩展手段。考试中可能结合架构风格判断扩展方案的合理性。
6.1 各风格扩展方式总览
| 风格 | 扩展方式 | 核心手段 | 扩展难度 |
|---|---|---|---|
| 数据流 | 流水线并行 + 过滤器水平扩展 | 各过滤器独立部署,多实例并行处理不同数据段;管道各阶段可重叠执行 | 较易 |
| 调用/返回 | 分层独立扩展 + 负载均衡 | 各层独立水平伸缩(如业务层加实例),通过负载均衡分发请求;增加服务器节点 | 中等 |
| 独立构件 | 事件处理器弹性伸缩 | 松耦合构件独立部署;消息队列解耦,按事件量动态增减处理器实例;天然适合分布式 | 容易 |
| 虚拟机 | 优化解释引擎 + 规则引擎实例扩展 | 解释器层面优化(JIT 编译、缓存);规则系统通过增加推理引擎实例实现分布式推理 | 较难 |
| 仓库 | 存储层扩展 + 计算节点扩展 | 分布式存储、数据分片、读写分离、缓存策略;黑板系统中增加知识源(KS)节点 | 中等 |
6.2 各风格详解
1. 数据流风格 — 流水线并行 + 过滤器水平扩展
- 每个过滤器是独立处理单元,可部署多个实例并行处理不同数据
- 管道各阶段天然支持流水线并行(阶段1处理后立即交给阶段2,无需等待整批完成)
- 瓶颈通常在最慢的过滤器,针对瓶颈过滤器增加实例即可
2. 调用/返回风格 — 分层独立扩展 + 负载均衡
- 分层架构中每层可独立扩展(如表示层、业务层、持久层各自水平伸缩)
- 通过负载均衡器在多个服务实例间分发调用请求
- 需注意层间接口的稳定性,扩展粒度受限于层次划分
3. 独立构件风格 — 事件处理器弹性伸缩(最易扩展)
- 构件间无直接依赖,仅通过事件/消息通信,扩展单个构件不影响其他构件
- 消息队列天然支持消费组,可动态增减事件处理器实例
- 微服务架构的基石,天然适合容器化弹性伸缩
4. 虚拟机风格 — 解释引擎优化(扩展较难)
- 主要靠优化解释器本身性能(字节码缓存、JIT 编译、热点分析)
- 规则系统可分布式化:规则引擎多实例部署,共享规则库和事实库
- 整体受限于解释执行的额外开销,性能不如原生编译
5. 仓库风格 — 存储 + 计算双维度扩展
- 存储层:分布式存储、数据分片(水平拆分)、主从复制、读写分离
- 计算层:构件围绕共享数据独立运行,可增加计算节点并行处理
- 黑板系统:增加知识源(KS)节点扩展求解能力;控制组件负责调度
6.3 记忆口诀
流加管,调加服,独加件,虚优引,仓扩存
- 数据流 → 加管道/过滤器实例
- 调用返回 → 加服务实例
- 独立构件 → 加事件处理器
- 虚拟机 → 优化引擎
- 仓库 → 扩展存储+计算