Software Architect · 模块 04

再强的团队,也会输给一套无法装进一颗脑子里的系统。

Cognitive load · bounded context · Conway's Law

§ 01

架构存在的意义是降低不必要的复杂度,而不是展示作者的智力肌肉。

复杂度不都是同一种

飞行员需要懂飞机的空气动力学,但不需要记住乘客座椅上每一颗螺丝的序列号。

intrinsic cognitive load 是领域本身的复杂度。金融系统里有钱、分录、限额、合规——这些是没法被抹掉的。extraneous cognitive load 则是架构额外制造出来的复杂度:偶发的依赖、各种"魔法"、不直观的 side effects、做同一件事有五种方式。

架构师的工作,是把团队从 extraneous load 中保护出来。好的架构不会让领域变简单,但它会让领域变得可理解。

Bounded context 削掉噪音

在机场,"gate"是登机口。在物流里,"gate"可能是仓库大门。同一个词,两个世界。

bounded context 是一道边界,边界内部的模型和语言保持一致。billing 里的 customer 和 support 里的 customer,往往根本不是同一个对象。强行做一个通用的"客户"模型,反而会放大 cognitive load:每个工程师都得记住所有领域的所有例外情况。

一个好的 bounded context 让工程师可以在局部工作:理解的就是这片区域的语言、invariants 和依赖。

§ 02

如果一次改动需要把整套系统装进脑子,那说明边界画得不对。

例子:一个团队拥有 checkout

餐厅一个班次端到端地负责整间厨房:食材、流程、出餐、品质。每一单都要打电话问总部,那班次也就没法干活了。

checkout 团队拥有 cart、pricing snapshot、payment intent、order creation 和 failure handling。它对 catalog 和 identity 有清晰的 API。它不会直接伸手去碰 warehouse,而是发布一个 OrderPlaced 事件。

这样切下来的好处是降低 cognitive load:团队端到端地理解自己负责的流,不用把整家公司都装在脑子里。

反例:shared everything 那一层

公用储物间挺方便,直到每个人都往里塞自己的工具,还不贴标签。

shared 这个目录经常变成杂物抽屉:validators、formatters、domain models、API clients、permissions、constants 全都堆在一起。任何一次改动都变得危险,因为没人知道还有谁在依赖这段代码。

shared 代码要么必须非常稳定,要么必须非常小。否则它就是在放大 coupling 和 cognitive load。

自检
  • 这个模块能不能脱离邻居模块单独解释清楚? - 系统里哪个地方过度依赖 implicit knowledge? - 哪些 shared 部分变更得太频繁? - team boundaries 和 architecture boundaries 是不是对齐的?