← 返回导航

深入理解:架构风格

风格从何而来、SOA到云原生演进史、风格匹配质量属性

配速记页 01-styles 使用。速记管应试,本页管「为什么」。

一、为什么会有「架构风格」

软件工程的历史,就是一部与复杂度搏斗的历史。代码量从一万行涨到一亿行,任何人的脑子都装不下全局——于是人类发明了两样东西:分解(拆成小块)和抽象(只看接口忘实现)。

架构风格就是「分解 + 抽象」的成熟套路:一类系统反复出现同样的问题,前人反复找到同样的解法,解法沉淀成模式。就像建筑学里的「哥特式」「巴洛克」,软件架构里沉淀出了管道、分层、事件驱动这些「式样」。

关键认知:风格不是发明出来的,是从成功系统里归纳出来的。所以每一种风格都天然绑定一类问题域。

二、一条主线:五种风格各自驯服哪种复杂度

1. 数据流风格 —— 驯服「加工顺序」的复杂度 编译器为什么天然是管道-过滤器?因为源码->词法->语法->语义->代码生成的加工链,每一级输出恰好是下一级输入,天然可组合。Unix 哲学「小程序通过管道连接」是这个风格的美学极致:ps aux | grep nginx | wc -l,三个程序互相不认识却协作完成统计。

2. 调用/返回风格 —— 驯服「依赖方向」的复杂度 分层的精髓不是「分成几层」,而是强制依赖单向化:下层不知道上层存在。OSI 七层是教科书案例。为什么这重要?单向依赖 = 下层可以独立替换(换了 MySQL 驱动不影响业务层)= 可移植性与复用的来源

3. 独立构件风格 —— 驯服「时间耦合」的复杂度 主程序-子程序是同步调用:调用方必须等。事件驱动把「我知道谁会处理」变成「我广播一下,谁关心谁订阅」——时间上解耦(不用等)、空间上解耦(不用认识)。GUI、消息队列、Spring 的 ApplicationEvent,血统都是隐式调用。

4. 虚拟机风格 —— 驯服「规则变化」的复杂度 当业务规则变得比代码还善变(保险费率、风控策略),把规则写进 Java 代码意味着每次改规则都发版。解释器/规则系统的思路:把「变化」从代码里抽出来,放进数据(规则库),引擎只负责执行。这是「数据驱动设计」的极致。

5. 仓库风格 —— 驯服「多视图共享」的复杂度 ERP 是典型:几十个模块(财务/库存/采购)围绕同一份主数据工作。数据库风格 = 被动中心数据 + 主动客户端;黑板 = 主动中心数据 + 竞争性知识源(谁有把握谁来写,适合语音识别这种没有确定性算法的场景)。

三、SOA -> 微服务 -> 云原生:一部「分布式再加权」三部曲

SOA(2000s)——为了「集成」 驱动力:企业收购兼并后,ERP、CRM、遗留系统需要打通。ESB 承担协议转换、路由、编排。问题:总线成为巨石,所有服务经过它,治理集中=部署耦合还在。

微服务(2014 前后)——为了「交付速度」 驱动力变了:不是集成,是互联网规模下的迭代效率。单体应用一个团队排队发布,改一行代码全量回归。微服务的革命性在于承认康威定律:系统结构 = 组织沟通结构,与其逆天改命不如顺势设计——一个服务一个团队,独立部署,故障爆炸半径缩小。 代价:网络不可靠、分布式事务、链路排障——这些复杂度从「框架层」转移到了「基础设施层」,这就为云原生埋下伏笔。

云原生(2018 至今)——为了「弹性与确定性」 微服务把复杂度甩给了运维(几百个服务的部署、扩缩、熔断)。云原生的答案是不可变基础设施:不「修」容器,直接换新的;声明式 API:你声明终态(要 3 个副本),控制器持续收敛。K8s 本质是一台「用代码固化了运维经验」的调度引擎。

四、关键洞察

  1. 风格没有好坏,只有匹配。匹配的判据不是「流行」,是质量属性优先级:实时控制选管道/规则,交互密集选事件驱动,数据密集选仓库,企业系统选分层+仓库混合。
  2. 真实系统是风格组合体。支付系统=分层(整体)+事件驱动(异步通知)+数据库风格(账务);MVC 在表示层,分层在整体。案例题答「组合」比答「单一」更显功力。
  3. 演化路径比静态分类更重要。论文里写「我们为什么从 A 演化到 B」,比「我们选了 B」有说服力得多——因为演化叙事天然包含权衡。

五、连到你的实战

六、延伸阅读