摘要
很多开发者对架构风格存在认知偏差:要么把它等同于 "整套系统的顶层业务规划",要么认为一个系统只能有一种架构风格。本质上,架构风格是架构层面的可复用设计范式,地位等同于代码领域的 GoF 设计模式,是软件工程实践沉淀下来的组件组织经验 。它既可以作用于整个系统,也可以作用于单个模块、一条处理链路;一个成熟的分布式系统,必然是多种架构风格的混合体。
本文系统梳理 Shaw-Garlan 经典架构风格体系,详解管道过滤器、仓库、黑板、分层、隐式调用等范式在日常开发中的真实落地形态;辨析 SOA、微服务、CQRS、微内核等现代广义架构模式的边界;结合 SpringCloud 微服务体系,拆解不同层级、不同模块分别采用的架构风格;给出可落地的选型方法论,并关联 ATAM/SAAM 架构评估逻辑,帮助开发者建立体系化的架构认知,避免 "为了风格而风格" 的过度设计。
一、架构风格的本质:架构级的 "设计模式"
1. 从代码设计模式到架构设计范式
Java 开发者对 GoF 23 种设计模式都不陌生:单例、工厂、策略、责任链...... 这些是代码级的可复用范式 ,解决的是 "类与对象怎么组织、怎么交互更优雅" 的问题。它们不是凭空发明的规则,而是前辈工程师在无数项目中沉淀下来的最佳实践,遇到同类问题可以直接套用,避免从零造轮子。
对应到更高的架构层级,架构风格就是系统层面的 "设计模式" :它定义了组件的类型、连接器的类型、以及它们之间的组合约束规则,解决的是 "系统组件怎么组织、怎么通信更合理" 的问题,同样是几十年软件工程实践沉淀下来的成熟模板。
二者的对应关系非常清晰:
- 代码级 → 设计模式,聚焦类与对象的交互,复用编码经验
- 架构级 → 架构风格,聚焦组件与连接器的组织,复用架构经验
2. 核心概念辨析:架构、架构设计、架构风格
很多人混淆这三个词,它们层级不同、角色不同,但联系紧密:
(1)架构(Architecture)
架构是系统的骨架与顶层设计思想 ,关注系统整体结构、核心诉求、各部分如何协同解决业务问题,是架构设计最终输出的结果,也是一种全局视角。
比如我们说 "电商系统采用微服务架构",描述的是系统整体的顶层形态与组织方式。
(2)架构设计(Architecting)
架构设计是一个动态过程 ------ 在架构原则的指导下,针对业务需求,从无到有设计系统结构、做技术选型、做质量权衡的完整活动。
上一篇讲到的 "合适、简单、演化" 三大原则、"识别 - 设计 - 评估 - 落地" 四步流程,就是架构设计的方法论。
(3)架构风格(Architectural Style)
架构风格是架构设计过程中可选用的可复用组织范式 ,是架构设计的 "工具箱" 和 "模板库"。
做架构设计不是凭空画方块连线,而是根据业务场景,从成熟的架构风格里选取合适的范式,组合、裁剪后落地。
三者关系总结
架构设计是过程,架构是过程输出的结果,架构风格是设计过程中使用的可复用模板。
而上一篇讲到的架构原则是设计的指导思想,架构风格则是思想指导下的经验沉淀与落地范式 ------ 原则管 "方向对不对",风格管 "怎么做更优"。
3. 两个关键认知(避免 90% 的误区)
(1)粒度灵活:不局限于整套系统
架构风格不是只能用在 "整个系统" 这个顶层粒度。它可以作用于:
- 系统级:整套业务系统的组织方式
- 子系统级:某个业务域的内部结构
- 模块级:单个服务内部的代码组织
- 链路级:一条请求 / 数据处理流水线的组织方式
很多时候架构风格是局部应用的 ------ 比如网关的请求处理链用管道过滤器,不代表整个系统就是管道过滤器架构。
(2)混合使用:一个系统可以并存多种风格
没有任何一个生产系统是 "纯某一种架构风格"。成熟的架构设计,是在不同层级、不同场景选用最合适的范式,组合在一起解决问题。
就像写代码不会只用一种设计模式,一个系统也不会只用一种架构风格。
二、经典架构风格与日常开发落地
经典架构风格以 Shaw-Garlan 分类为基准,是软考与教材体系的官方分类,按组织方式分为五大类。
1. 数据流风格:管道 - 过滤器(Pipe-Filter)
核心思想 :系统由一组过滤器组件和连接它们的管道组成;数据在管道中流转,每个过滤器只做输入到输出的转换,过滤器之间不知道对方的存在,由管道负责数据传递。
- 特点:组件独立、松耦合、可重排、可复用;不保存状态。
日常开发落地形态 :
- Servlet Filter 链 / Spring Interceptor :请求依次经过编码过滤、鉴权过滤、日志过滤,每个过滤器只处理 request/response,由 Servlet 容器负责流转,是最典型的局部管道过滤器应用。
- Spring Cloud Gateway 过滤器链 :GlobalFilter 与 GatewayFilter 按 Order 排序依次执行,路由、鉴权、限流、日志层层处理,配置调整顺序即可修改链路,无需改动代码。
- 大数据流式算子 :Flink/Spark 的 map、filter、flatMap 算子,每个算子只处理数据流,算子之间通过数据管道衔接,是标准的管道过滤器范式。
- Shell 命令管道 :cat log | grep error | sort | uniq,每个命令是过滤器,|是管道。
优缺点
✅ 组件解耦、可复用、可重排、支持并行处理
❌ 需要统一数据格式、交互性弱、错误处理链路长、不适合有状态业务
2. 数据中心风格
以中央共享数据为核心,组件围绕数据进行交互,分为仓库风格与黑板风格两种。
(1)仓库风格(Repository / 存储库风格)
核心思想 :存在一个中央共享数据仓库,所有业务组件独立,组件之间不直接调用,全部通过读写中央仓库完成数据交互。
- 特点:数据是核心,组件主动读写仓库;组件彼此不可见。
日常开发落地形态 :
- 数据仓库体系 :多个 ETL 任务、报表任务、分析任务,都读写 Hive 数仓;任务之间不直接 RPC 调用,靠数仓表交换数据。
- 遗留共享数据库系统 :多个业务程序共用一套数据库表,通过表完成信息交换,程序之间没有直接接口调用。
- 配置中心 :所有服务读写 Apollo/Nacos 配置中心,服务之间不直接传递配置,通过配置仓库共享。
优缺点
✅ 组件解耦、新增组件无需改动原有组件、数据集中管理
❌ 中央仓库是单点瓶颈、数据结构改动影响全部组件、隐式依赖难排查
(2)黑板风格(Blackboard)
核心思想 :三要素 ------ 黑板(共享数据存储区)、多个知识源、控制器。知识源观察黑板数据变化,满足条件时被控制器触发执行,计算结果写回黑板;知识源之间完全不交互。
- 特点:数据变化驱动执行;面向无确定求解算法的问题;多个知识源竞争产生结果。
日常开发落地形态 :
- 风控规则引擎 :黑板存放原始事件和中间风险特征;多个规则知识源读取黑板,产出风险标签,由调度器按优先级触发。
- 多工具 Agent 推理系统 :黑板存储中间推理状态;检索工具、计算工具、代码执行工具作为知识源,观察状态被调度执行。
- OCR、语音识别系统 :多个识别模块共享中间结果,逐步递进识别。
易混点:仓库风格是组件主动读写 数据;黑板风格是数据变化触发 知识源执行,前者主动,后者被动。
3. 调用 - 返回风格
(1)分层架构(Layered)
核心思想 :系统按职责垂直划分为多层,上层调用下层,下层不感知上层;每一层只和相邻层交互。
- 特点:职责分离、单向依赖、易于替换层级。
日常开发落地形态 :
- 后端经典三层 :Controller → Service → Repository/DAO → 数据库,是所有 Java 业务系统的标准范式。
- 网络 OSI 七层模型、TCP/IP 四层模型 。
- 数据分层 :ODS 原始数据层 → DWD 明细层 → DWS 汇总层 → DM 应用层。
优缺点
✅ 关注点分离、低耦合、层级可独立替换、便于团队分工
❌ 层级过多带来性能损耗、跨层调用破坏架构约束、底层改动可能层层传导
(2)主程序 - 子程序风格
核心思想 :主程序按顺序调用多个子程序,数据通过全局变量或参数传递,是面向过程时代的经典风格。
- 落地:C 语言命令行程序、早期结构化业务系统;现代开发中已很少整体使用,局部代码块仍有体现。
4. 独立构件风格:隐式调用(事件驱动)
核心思想 :组件不直接调用对方方法,而是发布事件;其他组件订阅事件,事件发生时由框架自动回调订阅者。
- 特点:发布者不知道订阅者是谁;高度解耦;异步执行。
日常开发落地形态 :
- Spring 事件机制 :ApplicationEventPublisher发布事件,ApplicationListener监听回调,组件之间无直接依赖。
- 消息队列发布订阅 :生产者发送 MQ 消息,消费者订阅消费,是分布式系统最常用的隐式调用落地。
- 前端 GUI 事件监听 :按钮点击事件触发回调函数。
优缺点
✅ 高度解耦、易扩展、异步削峰
❌ 调用链路不直观、调试困难、事务一致性复杂、事件顺序难保障
5. 虚拟机与解释器风格
(1)解释器风格
核心思想 :定义一套领域特定语言(DSL),构建解释器引擎,解释执行自定义脚本 / 规则。
- 落地:QLExpress/Aviator 规则引擎、SpringEL 表达式、低代码平台 DSL 解析。
(2)虚拟机风格
核心思想 :模拟一台虚拟机器,执行自定义指令集,屏蔽底层差异。
- 落地:JVM、Lua 虚拟机、Android Dalvik。
三、现代广义架构模式
工程实践中,微服务、SOA、CQRS 等常被广义称为 "架构风格",但它们并不属于 Shaw-Garlan 经典分类,而是工程化的架构模式 ------ 粒度更大,更偏向系统级工程实践。
1. SOA 面向服务架构
- 核心:ESB 企业服务总线,粗粒度服务,面向异构系统集成;
- 落地:企业内部 ERP、CRM 等系统打通,通过 ESB 做协议转换、路由、编排;
- 短板:ESB 容易成为全局性能瓶颈,服务粒度粗,迭代不灵活。
2. 微服务架构
- 核心:按业务边界拆分为独立部署的细粒度服务,服务间通过 API 通信;
- 落地:SpringCloud/Dubbo 微服务体系,每个服务独立数据库、独立迭代;
- 特点:技术异构、故障隔离、独立扩容;带来分布式事务、服务治理、运维复杂度问题。
3. CQRS 命令查询职责分离
- 核心:写操作(命令)与读操作(查询)分离,读写使用不同模型、不同存储;
- 落地:写操作走主库事务模型,读走冗余视图 / 搜索引擎 / 从库,独立优化读写性能;
- 适用:读写流量差异巨大、读场景复杂的系统。
4. 微内核架构(插件化架构)
- 核心:核心系统 + 插件模块;核心系统负责调度、插件管理,不包含具体业务逻辑;插件实现具体业务功能,可热插拔;
- 落地:IDEA 插件体系、商品打标规则引擎、可扩展规则平台。
四、高频辨析:易混淆架构风格对比
1. 核心对比总表
|----------|--------------------|-----------|---------------------------------------|-----------|--------------|-------------|
| 架构风格 | 核心特征 | 作用粒度 | 典型落地 | 核心优点 | 核心缺点 | 易错坑点 |
| 管道过滤器 | 数据流式流转,filter 互不感知 | 局部链路 | Servlet Filter、GatewayFilter、Flink 算子 | 解耦复用、可重排 | 交互性差、格式统一 | 和责任链模式混淆 |
| 仓库风格 | 组件读写中央共享数据,互不调用 | 系统 / 模块 | 数仓 ETL、共享数据库 | 解耦、新增方便 | 仓库瓶颈、结构改动影响大 | 和黑板风格混淆 |
| 黑板风格 | 数据变化触发知识源执行 | 系统 / 模块 | 风控引擎、多 Agent 推理 | 适合不确定问题 | 调度复杂、调试难 | 知识源主动执行 |
| 分层架构 | 垂直分层,上层调用下层 | 系统 / 服务内部 | SpringBoot 三层架构 | 职责分离、易维护 | 层级性能损耗 | 和微服务混淆 |
| 事件驱动 | 发布订阅,事件触发回调 | 系统 / 局部 | Spring 事件、MQ | 高度解耦、异步 | 链路不透明、一致性差 | 和管道过滤器混淆 |
| 微服务 | 按业务拆分独立服务 | 系统级 | SpringCloud | 独立部署、故障隔离 | 分布式复杂度高 | 是架构模式不是经典风格 |
2. 重点辨析
(1)管道过滤器 vs 责任链模式
- 管道过滤器:过滤器不知道下一个节点是谁,由管道 / 框架负责流转数据 ,过滤器只做输入输出转换;
- 责任链:节点持有下一个节点的引用,自己主动调用next.handle() ;
简记:管道过滤器是 "推着走",责任链是 "自己传"。
(2)仓库风格 vs 黑板风格
- 仓库:组件主动读写数据,数据是被动的;
- 黑板:数据变化触发知识源,知识源是被动触发的。
(3)分层架构 vs 微服务架构
- 分层:一个服务内部 按职责垂直切分,是技术维度的拆分;
- 微服务:系统级 按业务边界拆分为多个进程,是业务维度的拆分。
五、SpringCloud 微服务体系下的架构风格拆解
核心结论:微服务不是单一架构风格,而是多种架构风格在不同层级的混合体。
一个标准的 SpringCloud 微服务系统,从全局到局部,至少同时存在 5 种架构风格。
1. 系统全局:微服务架构模式
整个业务系统按业务域拆分为商品服务、订单服务、支付服务、用户服务等独立微服务,服务间通过 HTTP/RPC 通信,独立部署、独立扩容。
- 这是系统级的架构模式 ,定义了服务之间的组织方式。
2. 网关层:管道过滤器风格
Spring Cloud Gateway 作为流量入口,内部请求处理链路是典型的管道过滤器:
- 全局过滤器、路由过滤器按 Order 排序依次执行;
- 每个过滤器只处理 ServerWebExchange,不直接依赖其他过滤器;
- 网关框架负责把请求沿链路传递,过滤器只做输入输出转换。
3. 单个服务内部:分层架构风格
每个微服务内部,依然遵循 Controller → Service → Repository 的经典分层架构;部分 DDD 实践会进一步拆分为接口层、应用层、领域层、基础设施层。
- 这是服务内部的架构风格 ,定义了代码的组织方式。
4. 跨服务异步协作:事件驱动(隐式调用)风格
服务之间的异步解耦场景,采用消息队列实现事件驱动:
- 订单创建完成,发布 "订单创建事件";
- 库存服务、积分服务、通知服务订阅事件,各自执行本地业务;
- 发布方不需要知道订阅方是谁,实现服务解耦。
5. 配置与元数据中心:仓库风格
Nacos/Apollo 配置中心、元数据中心,扮演中央数据仓库的角色:
- 所有微服务读写配置中心,服务之间不直接传递配置;
- 配置变更通过配置中心广播,服务被动更新,是典型的仓库风格落地。
这就是架构风格的真实面貌:没有哪个系统是 "纯某一种风格",成熟的架构都是在不同层级、不同场景选用最合适的范式,组合在一起解决业务问题。
六、架构风格选型方法论
架构选型不是 "选最火的",而是 "选最适配的",结合本系列第一篇的三大原则(合适、简单、演化),形成四步选型法。
步骤 1:识别核心诉求与约束
先明确场景:
- 是一条数据处理链路,还是整套业务系统?
- 核心痛点是性能、可维护性、可扩展性,还是集成性?
- 团队规模、技术栈、运维能力如何?
步骤 2:按粒度匹配风格层级
- 整条数据处理链路 :优先考虑管道过滤器;
- 共享数据为主的系统 :优先考虑仓库风格;
- 业务系统内部代码组织 :优先考虑分层架构;
- 跨服务异步解耦 :优先考虑事件驱动;
- 系统级服务拆分 :考虑微服务、SOA;
- 规则多变、需扩展 :考虑解释器、微内核。
步骤 3:质量属性权衡
每种架构风格天然倾向某些质量属性,牺牲另一些:
- 追求可修改性:分层、微内核、管道过滤器;
- 追求高性能:管道过滤器、CQRS;
- 追求高可用:事件驱动、微服务;
- 追求简单性:分层、单体 + 仓库。
步骤 4:避免过度设计,渐进演化
- 小型内部系统,单体分层就足够,不要强行微服务;
- 简单过滤链路,用普通 Filter 就好,不要引入复杂的规则引擎;
- 预留扩展点,但不要提前实现不需要的架构。
七、延伸:架构风格与 ATAM/SAAM 评估
架构风格不是孤立的知识点,它是架构评估方法的核心评估对象。
1. ATAM 架构权衡分析法
ATAM 的核心是评估多个相互冲突的质量属性,而架构风格是影响质量属性的核心变量 。
- 构建效用树时,质量属性是树干,具体场景是叶子;
- 评估时,就是分析 "采用某种架构风格,对各个质量属性带来了什么影响";
- 识别敏感点(影响一个属性)和权衡点(同时影响多个冲突属性),本质都是架构决策带来的。
比如:引入微服务架构,提升了可修改性、可用性,但降低了性能、增加了复杂度 ------ 这就是典型的权衡点。
2. SAAM 场景架构分析法
SAAM 侧重评估可修改性,通过业务场景验证架构优劣。
- 架构风格直接决定了 "新增一个需求,改动范围有多大";
- 分层架构、微内核架构在可修改性上天然优于单体、仓库风格。
八、体系化总结与核心复习要点
- 本质定位 :架构风格是架构级的可复用设计范式,类比代码级的 GoF 设计模式,是工程经验的沉淀与复用。
- 概念边界 :架构设计是过程,架构是结果,架构风格是设计过程中使用的模板;架构原则是指导思想,架构风格是落地范式。
- 经典分类 :数据流(管道过滤器)、数据中心(仓库、黑板)、调用返回(分层、主程序子程序)、独立构件(隐式调用)、虚拟机与解释器。
- 现代模式 :微服务、SOA、CQRS、微内核是工程化架构模式,常被广义称为架构风格。
- 落地原则 :系统级用微服务做拆分,服务内部分层,网关 / 处理链路用管道过滤器,异步解耦用事件驱动,规则多变用微内核 / 解释器。
- 选型核心 :没有最好的风格,只有最合适的组合;匹配业务场景、团队能力、发展阶段,避免过度设计。
- 评估关联 :ATAM/SAAM 架构评估,本质就是评估架构风格对质量属性的影响。
下一篇:《高性能架构实战:从单机到分布式落地》,将深入拆解性能优化的全链路方案。
系列上篇:《Java 架构入门:3 大原则 + 4 步流程》
📚 我的技术博客导航:点击进入一站式查看所有干货