# 02. 权衡 (Trade-offs)

如何沿着 trade-off 的不同轴线比较架构决策、如何谈论复杂度的代价,以及如何选出的不是抽象意义上“最好的方案”,而是适合当下语境的那一个。

- **Author:** Fedor Chishchin
- **Level:** advanced
- **Reading time:** 约 25 分钟阅读
- **Published:** 2026-05-23
- **Source:** https://fedorthinks.com/zh/learn/software-architect-02-tradeoffs

---

## 1. 核心观点

架构师不去追逐 best practice。他要做的是,命名选择的轴线,以及每个轴线上需要付出的代价。

### 没有代价的“决策”不算决策

> 飞机比火车快,但更贵、更挑天气、还不会把你送到市中心。"飞机更好"是一种糟糕的架构语言。

trade-off 就是用一个属性去交换另一个属性。系统里最常见的几条轴:latency vs. throughput、consistency vs. availability、simplicity vs. flexibility、time-to-market vs. maintainability、operational cost vs. development speed、vendor control vs. build cost。

专业的对话听起来是这样的:"我们选 managed Postgres,因为团队小,运维速度对我们而言比对 storage layer 的完全掌控更重要。"或者:"我们现在不引入 Kafka,因为我们用不到 replay 和 high throughput,但 operational complexity 明天就会变得非常真实。"

### 复杂度必须买到一个具体的能力

> 在一居室里塞一套工业级厨房,做饭是能做。住人就难了。

复杂度并不总是坏事。有时它是必要的:multi-region、event sourcing、sharding、service mesh、CQRS、Kubernetes。但每一项都必须买到一个具体属性——这个属性要么已经重要,要么几乎可以肯定即将变得重要。

如果团队说不清这份复杂度到底买到了什么,通常就是 over-engineering。如果团队为了"简单"而对已经存在的痛点视而不见,那是 under-engineering。

## 2. 例子与反例

只有当 trade-off 真正改变了决策,它才有用。

### 例子:REST 还是 GraphQL

> 菜单适合菜式标准化的餐厅。沙拉自选台适合每位客人都想自己搭配的场景。

REST 适合资源稳定、缓存有效、客户端形态相似、API 需要对外集成保持简单的场景。GraphQL 适合客户端多样、数据形态各异、前端经常被 overfetching 或 underfetching 折磨的场景。

trade-off:GraphQL 把灵活性交给客户端,代价是 observability、字段级 authorization、缓存、rate limiting 和性能控制都变得更复杂。REST 运维上更简单,但可能让 endpoint 数量增多,并把客户端逼到多轮请求。

### 反例:"大公司就是这么做的"

> 机场有塔台,但这不等于自行车停车场也得有一个。

抛开 Netflix、Uber、Amazon 各自的体量,直接抄它们的架构,就是 cargo cult。大公司的负载、团队、compliance、legacy 和宕机成本都和你不同。他们的决策在他们的语境里也许正确,搬到你这里却可能有害。

架构师必须能这样说出口:"是的,这是行业里的 pattern。不,我们的问题还不在那一档。"

#### 自检

- 当前决策落在哪些 trade-off 轴上?
- 这份复杂度买到了什么?
- 如果选最简单的方案,会发生什么?
- 哪个信号会告诉我们,该加复杂度了?

下一模块:[技术债](./software-architect-03-technical-debt)。
