第 2 章拆解(上)— 技术栈是什么,架构从哪些视角看
技术栈是什么,架构从哪些视角看
这一章(及紧随其后的 03、04)回答动手之前必须先想清楚的事: 我们说的「技术栈」 到底指什么?「架构」这个词被整个行业用得面目全非,还怎么拿它做决策? 书里给出的出路:不追唯一定义,认领视角——每个视角看清一件事,合起来就是一次完整的选型论证。 本节先讲视角;下一节(03)讲 Web 应用自己的几种架构和工单系统的选型推演; 04 讲生态里有哪些候选(数据库、框架、前端)。 本章全程几乎没有代码,但它是全书最贵的一章:后面所有的技术决定都在这里挂账。
1. 这一章在全书链条里的位置
第 1 章论证了「Rust 可以写 Web」。但「可以」不等于「该用它、以及该配哪些组件」。 这本书要造的是一个会陪读者走过 12 章的真实项目(工单系统),选错的代价会一路复利。 所以第 2 章停下来,把两件最容易被拍脑袋的事讲透:什么是技术栈、怎么看架构。 作者的原话:先定义需求,再选技术栈,绝不能反过来1。
2. 顶层全景:一条「想清楚」的流水线
① 钉死词义:stack 本是「一摞」;tech stack = 为某个目的经常搭配使用的技术集合
② 认领视角:架构无法唯一定义 → 从六个视角各看一件事
③ 认识候选:分层 / SOA / 事件驱动… 每种架构带着它自己的视角
④ 按项目落地:工单系统走一遍决策流程(评估维度、打分表)→ 04 选具体技术
图说:先词义、再视角、再候选、最后才是具体产品——顺序颠倒就是拍脑袋。主线例子(本章三篇共用):一个工单(ticket)从提交到完成。 后面讲分层架构时,它会在「表现层 → 业务层 → 持久层」之间流动; 讲事件驱动时,它的每次状态变化会产生一个事件;讲选型时, 它是被评估的每一个候选要服务的对象。
3. tech stack:先把词钉死
这一节只解决一件事:当有人说「我们的技术栈是 XX」时,他到底在说什么。
书里的教法很有意思——先查字典。stack 的本义来自农业:一摞干草堆(haystack), 是「乱糟糟垒在一起的一大堆」,而不是整齐有序的架子。用这个本义反推, tech stack 的直觉应该是:** loosely coupled(松耦合)的东西一摞一摞往上叠、数量还大**—— 但这两个直觉都不必然成立:组件可以很紧耦合(换掉任何一个都难,像从草垛底下抽一根换一根), 数量也可以很少2。
书里的正式定义(一句话,值得背):
技术栈 = 一组经常搭配在一起、为某个特定目的(比如 Web 开发)服务的技术。3
两个推论:
- 组件不必为 Web 而生。 经典组合 LAMP(Linux + Apache + MySQL + PHP/Perl/Python)里, Linux 是通用操作系统——「你一旦 routinely 拿它做 Web,它就成了栈的一部分」3。
- 栈是塑料做的,不是铸铁做的。 没有「唯一正确」的栈;把现成的方案当速写参考可以, 但专业环境里应该一个组件一个组件地评估,对着要做的产品选4。
书里最重要的选型规矩:
先定义需求,再选技术栈——绝不是反过来。4
这一句话是本章的题眼。后面决策流程那套打分表,就是为执行它准备的(见 03)。
4. 「架构热」:一个词被拉伸到失真
这一节解决:为什么「架构」没法用一句话定义,以及书里采用的应对策略。
书的开场连引三句业内名言,只为让你体会这个词的混乱程度:
- Martin Fowler(企业应用架构模式的作者):「软件行业乐此不疲地拿词来用, 把意思拉伸到无数微妙矛盾的境地。最大的受害者之一就是 architecture。」5
- Ian Gordon(《Essential Software Architecture》):「我暗暗怀疑,架构是专业软件开发圈 里被用得最多、被懂得最少的词之一。」6
- Simon Brown(《Software Architecture for Developers》):「architecture 对不同的人 意味着完全不同的东西,网上漂着一大堆不同的定义。」7
书里给出的出路:不找定义,找视角。 同一个东西,从不同立场看,看到的是不同的「架构」—— 没有一个模型能独占这个词,但每个视角下的说法都有效8。
4.1 两个「假建筑」把「视角」讲透
书里用了两个建筑类比,值得原文接住:
第一个是匈牙利 Tata 公园里的「假废墟」。 作者旧居前的一个英国式花园里, 有一片浪漫的中世纪废墟——其实是现代人造出来装着古旧的。它不能住、不能防御, 但它有 purpose(目的):取悦游客。软件也一样:哪怕造一个「残骸」,也得先有目的; 先找到利益相关者(stakeholder,对软件有要求的人),哪怕只有自己一个人。9
第二个是巴塞罗那圣家堂(Sagrada Família)的悬链模型。 教堂设计时, 高迪团队把装了沙的沙袋吊成一张倒挂的网:每一根绳子的位置就是教堂拱顶的镜像, 沙袋重量模拟荷载。绳子全部对称下垂,说明静力平衡。这个模型「是这座教堂的架构」吗? 从静力分析的角度,是;但蓝图、施工图、模型各有各的角度,没有一个能独占 「教堂的架构」这个词——它们各自从某个视角描绘(delineate)并偶尔体现(manifest)它10。
软件架构同理。 Fowler 还有个提醒划定了类比的边界:「企业应用不包括汽车燃油喷射」—— 建筑里的地基工程,在软件里没有对应物;别把类比拉得太远11。
5. 六个视角:一次完整的「想清楚」
这一节是全章的承重墙。 视角按软件开发的进程排:每个视角对应「谁、在什么阶段、 回答什么、把什么决定留下」。我们逐个讲。
5.1 方案设计(solution design):业务专家的地盘
最先定义需求的人,是懂业务的人。书里的行话链条:
stakeholder(利益相关者)定出业务概念 → 这些概念就是业务逻辑(business logic), 也叫领域逻辑(domain logic)→ 设计它们的人叫方案架构师(solution architect), 他们的工作叫方案设计(solution design)。12
方案设计定的是:系统里的术语、基本构件块、它们的关系和行为(术语表式的蓝图,不含任何技术选型)—— 比如工单系统里,「工单」「阶段」「状态」这些词各自的含义和流转规则。 注意这一层完全不讲技术。 选什么数据库、什么语言,是后面视角的事。
书里还澄清了一对常被职位名称弄混的角色:软件架构师(software architect)和 软件工程师(software engineer)。别被名字骗了:他俩干的都是架构的活, 只是分辨率不同——架构师看系统:组件怎么划、基建怎么定、技术栈定到什么程度; 工程师看自己手上那一两个项目:在里面细化技术栈、保证集成得上12。
5.2 方法论(methodology):自顶向下还是自底向上
解决什么问题: 需求定了之后,实现过程本身怎么组织。
书里给了两个相反的方向13:
- 自顶向下(top-down): 像「切大象」——把大问题切成好管理的小块;
- 自底向上(bottom-up): 等结构开始重复时,把它抽出来(factor out)。
方法论(methodology)= 一套自洽的方法(规定先做什么后做什么),把开发从头到尾推下去;工作流(workflow)是其中「一件工作怎么流转」的具体路径。 它跟编程范式(paradigm)的区别只在野心大小——最老的方法论「结构化编程」 同时也是一种范式:把吃不下的初始问题切成「要么平凡可解、要么继续切」的小块14。
瀑布模型(Waterfall)怎么来的: 它照搬制造业:分析 → 设计 → 开发 → 测试 → 部署 → 维护,每一阶段都以前一阶段完成为前提15。
瀑布的致命伤: 软件里你「做不完」一个阶段——需求会变,开发中理解会加深、 设计得返工。把阶段封死,就把「软」字从软件里抽掉了。16
敏捷(Agile)怎么接班: RAD、极限编程(XP)、Kanban、Scrum 这一批, 强调的是「拥抱变化是软件开发的天然属性」,走迭代式,把开发看成软件生命周期里 一个永不结束的循环16。
一个诚实的观察(书里很妙的一点): 现实中没有方法论被真正丢弃——它们演化、 合并、复现。看板(Kanban)的列,就是瀑布阶段的复活:没有一个用户故事 能同时处在两列(两个阶段)里,典型工作流照样把故事从左(开始)拖到右(完成)17。 也就是说:敏捷不是推翻瀑布,而是给「阶段」松了绑。
5.3 基础设施(infrastructure):运维也有一份架构
解决什么问题: 应用跑在哪、跟谁说话、拿什么存——这些问题不止开发者关心, 运维(Ops/DevOps)工程师同样有视角。基础设施和架构的界线本来就模糊, 两边最终都要重度使用定下来的那些系统组件18。
书里列的基础设施清单(每一个都是后面章节的主角):
| 类别 | 候选 |
|---|---|
| 操作系统 / 文件系统 | Linux、Windows… |
| 组件间通信 | TCP/IP、HTTP、MQTT |
| 持久化 | 关系库、嵌入式库、NoSQL |
| 工程支撑 | 版本控制(记录每次代码变更)、容器化、编排、CI/CD(持续集成/持续交付:推送即自动构建、测试、发布) |
| 第三方组件 | Web 服务器、负载均衡、缓存 |
| 运行平台 | 平台与运行时 |
这一视角的要点是:这是离「技术栈」最近的视角——但书里刻意到此为止, 把话头让给下一个视角19。(容器化和编排正是第 9 章;CI/CD 第 3 章就接入。)
5.4 软件架构(software architecture):构件块决定了「配」还是「写」
解决什么问题: 明确一个更窄的「架构」:这里说的是「用不能自己跑、要嵌进 你的软件里才能活的构件块来造东西」的那种开发——区别于「配」一个现成系统 (比如用 WordPress 装一个电商站,几乎不写代码)20。
这个视角下要回答的决定:
| 决定 | 选项 |
|---|---|
| 环境 | 服务器 / 客户端 / 桌面 |
| 语言 | 按目标类型(编译/解释/JIT)、范式、内存模型(手动/托管)、类型系统(静态/动态)、抽象层、领域来分类 |
| 框架 | 「现成的、常预配置的库集合,解决某技术领域最常见的问题」 |
| 适配器(adapters) | 兼容层:让程序接上数据库、硬件等其他软件 |
| 集成(integration) | 帮「A 的输出」翻译成「B 的输入」的库集合 |
pattern(模式)和 architecture(架构)的分界(书里采用的工作定义):
- 模式 = 对常见问题的一次反复出现的设计解法;
- 架构 = 以整个系统为目标去应用的模式。21
两家权威的书还吵过这两个词怎么划(Michaela Ghidersa vs Mark Richards & Neal Ford, 口径正好相反)——书里不站队:术语够用就行,别 cling(死抓)在上面22。
这一视角最要紧的一句话:框架不能无视架构——框架本身就隐含了一个架构决定, 因为框架实现了某个模式。所以「团队挑框架的那一刻,架构决定就已经做掉了」。23 这就是为什么 Rust「缺全家桶框架」是条真短板(第 1 章讲过): 没人替你预做架构决定,你每个决定都得自己做、自己扛。
5.5 代码组织(code organization):目录结构也是架构
解决什么问题: 代码往文件和文件夹里怎么放——它也是一种架构, 可能贴近其他架构模式,也可能不贴24。
两个极端:
- 少管你的框架: 目录随你定;
- 约定优于配置的框架: 给目录结构赋予意义,让结构直接映射到 MVC 之类的模式, 「能藏多少藏多少,让你专注业务逻辑」24。
第 3 章会专门展开各种代码组织方案(按架构切、按功能切、按模式切……)—— 它是第 2 章这个视角的直接落地。
5.6 模块化(modularity):「单体」与「模块化」只差一个视角
解决什么问题: 抽象可以一层套一层,套到哪层都有模块。 关键是:「单体应用」不等于「没有模块」——说一个系统单体,意思是 跟松耦合、可独立部署的服务比,它模块化的程度不够,而不是说它内部一团浆糊25。
书里给的这把尺很哲学,但实用:
| 视角 | 关注 |
|---|---|
| 单体(monolithic) | 把系统当一个整体交付 |
| 模块化(modular) | 交付自给自足、可拼成整体的模块 |
组件还可以物理分开(不同真机或虚拟机),那就有了 n-tier(多层)和分布式架构25。
6. 架构示例:五种常见架构各解决什么
这一节把「视角」落到实处:五种最常见架构,逐个按「解决什么问题 → 怎么转 → 代价」讲。
6.1 分层架构(layered):默认中的默认
解决什么问题: 应用逻辑混杂在一起会互相缠死。 分层的做法:把逻辑按角色切成几层,层层叠放,只允许依赖下一层—— 这一刀切下去,同时做到了关注点分离和解耦(依赖单向、访问受限,防缠绕)26。
最少三层:
| 层 | 职责 |
|---|---|
| 表现层(Presentation) | 对外的界面:Web 页面、命令行、API;系统与外界的唯一通道 |
| 业务层(Business) | 核心业务/领域逻辑;通常是表现层与持久层之间的通信层 |
| 持久层(Persistence) | 把数据存成以后能可靠取回的样子(不一定是数据库) |
主线例子走一遍(工单「创建 → 完成」):
用户在界面填一张新工单,点提交
│ ① 表现层收到请求,不动业务规则,转下去
▼
业务层:校验(标题非空)、定初始状态(Created)、
决定是否通知订阅者
│ ② 只有业务层懂规则;它要存了,才找下一层
▼
持久层:把工单写成一行(标题、状态、时间戳)
│ ③ 写完了原路返回;表现层拿到结果,渲染「创建成功」
▼
用户看到新工单出现在列表里
——之后每次状态流转(Estimated → Open → … → Done),
都重复同一趟三层往返。
图说:每一层只跟直接下层说话;层与层之间是单向依赖。
(这个流程是照书里三层职责的原文口径走的演示;具体状态名出自第 2 章原文。)后来长出来的分层变体(都来自应用架构师的视角):
- 六边形架构(hexagonal): 核心逻辑与外部世界之间,只通过端口(port)和适配器(adapter) 通信——表现层、日志、监控都是不同的 adapter。核心不认得 HTTP,只认得端口27。
- 洋葱架构(onion): 与六边形同思路:核心定义干净接口,外层去实现它27。
- 整洁架构(clean): 四个同心壳:最里是企业业务逻辑(实体),往外是用例, 再往外是三类适配器(网关、控制器、展示器),最外是 UI 等外部接口27。
- 垂直切片(vertical slices): 按业务把各层竖着切开:这个业务需要几层就留几层, 不强迫所有业务共用同一套层数27。
逻辑层再物理分开部署,就升级成 n-tier(多层)架构——比如表现层跑在用户浏览器、 业务层跑在服务器、持久层跑在数据库机,就是经典三层(two-tier/three-tier 的说法由此来)。
6.2 面向服务的架构(SOA):把应用切成服务
解决什么问题: 一块巨石难管 → 按职责切成边界清晰的服务。 SOA 仍是分层的、部分垂直切片的,但有一个关键共性:共享一个数据库28。
微服务是 SOA 的激进后代。 它破了共享数据库的规矩,因为微服务追求 可独立部署——每个服务连自己的库一起部署,边界才算干净29。 书里还点了两个常见误解:
- 图里的「事件总线」不是必须的:可以连部分服务,也可以没有;
- 图里的「UI」不一定是给人看的图形界面:它可以是任何 API——实际上常见做法是 把归属相同的 UI 合并,下面统一接 API 层29。
为什么本书不选微服务: 第 1 章已声明这不是微服务书;这里给出的架构学理由是: 微服务的收益(独立部署、独立伸缩)要用运维复杂度来换——服务多了, 编排、监控、分布式追踪全都得跟上。对一个教学项目和一个中小团队,单体加好模块是更诚实的起点。
6.3 事件驱动架构(event-driven):回到一个循环
解决什么问题: 请求方不想干等;处理方想按自己的节奏来。 最简单的形态朴素得惊人:一个循环——每个周期从事件源取一个事件, 找匹配的 handler(处理器)把事件递过去;没有匹配的 handler 就忽略,取下一个。 handler 事先不知道事件什么时候来,所以「看起来像异步」——其实只是一个不停转的循环30。
- GUI 程序就是这个形态:消息循环不用你写,工具包自带;
- Web 服务器也是:请求即事件,handler 备好响应,响应本身又可以触发新事件;
- 高效形态会把事件循环和具体处理分到不同线程:循环永不被慢操作堵住, 长活交给 worker,worker 干完用新事件交回结果31。
这一架构和第 8 章的通知队列、第 12 章的实时更新是同一条线的三次现身: 事件 → 排队 → 有人消费。现在先记住这个循环,后面两处你会认出它。
7. 作者的判断与证据(分开标)
有出处的:
作者自己的评估:
- 「从视角看架构」这个应对策略本身是作者(及他引的 Simon Brown)的取舍,不是行业标准方法;
- 「Rust 缺全家桶框架所以架构决定都要自己做」是把第 1 章短板推演到选型层面的作者推论;
- 「敏捷只是给瀑布松绑」是对看板列的观察性解读。
8. 边界与局限
- 术语口径不统一: 作者自己承认 architecture style 与 pattern 的划界在业内有两派 相反说法,本书的工作定义够用而已22——出门撞见别的口径,不必惊讶。
- 架构示例是导览不是手册: 每种架构一节,够做选型判断,不够落地实施; 微服务的分布式一致性(CAP、Saga 等)要到第 2 章后半(04)和第 10 章才展开。
- 视角清单是「最常见」而非「完备」: 安全架构、数据架构等视角本书未单列, 散在各章(第 7 章讲访问控制、第 10 章讲缓存,其实就是那两个视角的展开)。
9. 可带走的
- 技术栈的正确定义: 一组为某目的经常搭配使用的技术;先需求、后选型, 顺序反过来就是拍脑袋。
- 「架构」没有唯一定义,但有视角: 方案设计(业务概念)、方法论(过程组织)、 基础设施(跑在哪)、软件架构(构件与框架)、代码组织(目录)、模块化(切到哪)—— 一次完整想清,六件事各答一个阶段的问题。
- 方法论不是教义: 瀑布的死穴是「阶段封死」,敏捷的解法是给阶段松绑 (看板的列就是瀑布阶段的复活)。
- 分层三层是最小可用架构: 表现 / 业务 / 持久,单向依赖;六边形、洋葱、整洁、 垂直切片都是它的变体——共同点是「核心不认得外部世界」。
- 微服务 = SOA − 共享数据库 + 独立部署; 代价是运维复杂度;教学项目和中小团队, 好模块的单体是更诚实的起点。
- 事件驱动最简形态就是一个循环: 取事件 → 找 handler → 递过去;高性能的关键是 循环与处理分线程,循环永不堵。
- 挑框架 = 买它隐含的架构决定: 全家桶帮你预做的决定,Rust 生态里大多要自己扛—— 这是「缺全家桶」这条短板的真实形状。
10. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| stack 字典义与 LAMP | Selection of a Tech Stack(Definition of a tech stack) | text/11-fm-definition-of-a-tech-stack.txt:7(搜「haystack」)、:10(搜「LAMP」) |
| tech stack 定义 | 同上 | text/11-fm-definition-of-a-tech-stack.txt:16(搜「collection of technologies」) |
| 先需求后选型 | 同上 | text/11-fm-definition-of-a-tech-stack.txt:22(搜「define our requirements」) |
| Fowler/Gordon/Brown 引文 | 同上(The architecture frenzy) | text/12-fm-the-architecture-frenzy.txt:7(搜「delights in taking words」)、:16(搜「sneaking suspicion」)、:25(搜「means many different things」) |
| 假废墟与目的先行 | 同上 | text/12-fm-the-architecture-frenzy.txt:56(搜「romantic ruins」) |
| 圣家堂悬链模型 | 同上 | text/12-fm-the-architecture-frenzy.txt:78(搜「statical model」) |
| 方案设计/方案架构师 | 同上 | text/12-fm-the-architecture-frenzy.txt:102(搜「solution design」) |
| 自顶向下/自底向上 | 同上 | text/12-fm-the-architecture-frenzy.txt:122(搜「slicing the elephant」) |
| 方法论定义与结构化编程 | 同上 | text/12-fm-the-architecture-frenzy.txt:128(搜「consistent collection」) |
| 瀑布六阶段 | 同上 | text/12-fm-the-architecture-frenzy.txt:134(搜「Waterfall」) |
| 敏捷与看板列 | 同上 | text/12-fm-the-architecture-frenzy.txt:157(搜「Agile」)、:160(搜「columns」) |
| 基础设施清单 | 同上 | text/12-fm-the-architecture-frenzy.txt:166(搜「infrastructure」) |
| 软件架构(构件块口径) | 同上 | text/12-fm-the-architecture-frenzy.txt:219(搜「building blocks」) |
| pattern 与 architecture 分界 | 同上 | text/12-fm-the-architecture-frenzy.txt:285(搜「recurring design solution」) |
| 框架隐含架构决定 | 同上 | text/12-fm-the-architecture-frenzy.txt:295(搜「implied」) |
| 代码组织视角 | 同上 | text/12-fm-the-architecture-frenzy.txt:310(搜「half a success」) |
| 单体≠无模块 | 同上 | text/12-fm-the-architecture-frenzy.txt:319(搜「not modular enough」) |
| 分层三层职责 | 同上 | text/12-fm-the-architecture-frenzy.txt:331(搜「distinct roles」)、:344(搜「Presentation」) |
| 六边形/洋葱/整洁/垂直切片 | 同上 | text/12-fm-the-architecture-frenzy.txt:360(搜「Hexagonal」)、:363(搜「Onion」)、:366(搜「Clean architecture」)、:370(搜「vertical slices」) |
| SOA 与共享数据库 | 同上 | text/12-fm-the-architecture-frenzy.txt:379(搜「well-separated services」)、:389(搜「shared database」) |
| 微服务拓扑与事件总线非必须 | 同上 | text/12-fm-the-architecture-frenzy.txt:397(搜「microservices architecture」)、:402(搜「not mandatory」) |
| 事件循环 | 同上 | text/12-fm-the-architecture-frenzy.txt:414(搜「loop that processes events」) |
| Points to remember | 同上 | text/14-fm-points-to-remember.txt:1(搜「Points to remember」) |
5.7 六个视角再展开(每个视角多走一步)
方案设计的两个分辨细节。 其一:业务概念也叫领域逻辑(domain logic)—— 「这些概念属于业务域,即公司的主营画像」;公司里通常由业务专家设计, 「他们懂用例、目标群体和问题本身,对怎么解决有受过训练的直觉」。 其二:架构师与工程师的分工不是高低,是分辨率——「别被命名迷惑: 他俩都与架构有莫大的关系,只是聚焦的层级/分辨率不同」;工程师也必须 「对方案和系统有恰当的理解」,否则集成会出错32。
方法论家族逐个认脸(书里点了名,各自一句话定位):
- 结构化编程:最老的方法论,同时也是一种编程范式——自顶向下, 把吃不下的问题递归地切成「平凡可解」或「继续切」;
- 瀑布:照搬制造业的六阶段,前阶段不完后阶段不开;
- RAD(rapid application development):敏捷家族一员, 强调对变化需求的快速反应;
- XP(极限编程):把「拥抱变化」推到工程实践层(测试先行是它的招牌, 第 6 章会回来);
- Kanban:看板,把瀑布的「阶段」复活成「列」,一张卡同时只在一列;
- Scrum:迭代冲刺 + 固定角色仪式的敏捷框架。
书里对整族的态度:「现实中几乎没有任何方法论被真正丢弃——它们演化、 合并、复现。」 看板的列就是瀑布的借尸还魂,这条观察比任何方法论宣言 都更能帮人看懂真实团队的板子33。
基础设施清单逐项的用途预告(这份清单在第 9–13 章各有归宿):
| 清单项 | 本书落地处 |
|---|---|
| 版本控制 / CI/CD | 第 3 章接 CI;第 12/13 章持续出现 |
| 容器化 / 编排 | 第 9 章整章 |
| 通信层 TCP/IP、HTTP、MQTT | HTTP 全书;MQTT 未展开 |
| 持久化三选 | 第 2 章选型、第 4 章换装 |
| Web 服务器 / 负载均衡 / 缓存 | 第 12 章 lighttpd;第 10 章缓存 |
| 平台与运行时 | Tokio 就是那个运行时 |
「基础设施与架构的界线本就模糊,双方都要重度使用定下来的组件」—— 这句是 DevOps 文化在 2026 年已成默认的起点34。
软件架构视角的「配 vs 写」分界再敲一次: WordPress 装电商站是「配」 (几乎不写代码);用 JSON 库和数据库适配器是「写」(配置也有,但必须编程)。 「框架隐含架构决定」那句推论也值得再引:挑框架时你买的不只是功能, 还有它替你做掉的那些架构决定——Rust 缺全家桶,所以这些决定全都 回到你自己手上(这就是第 2 到 10 章的内容目录)35。
模块化视角的 n-tier 预告: 逻辑分层一旦物理拆开(表现层在浏览器、 业务层在服务器、持久层在数据库机),就从「分层」升级为 n-tier(多层) 架构——「层」是逻辑角色,「tier」是物理部署,两个词别混36。
6.4 五种架构再展开(边界与误区的更多细节)
分层架构的两个误警。 误警一:分层 ≠ 代码目录。「我们不必沿层的边界 组织代码」——可以跟方案设计的概念走,换来与业务专家共用的语言; 「分层架构是瞄准软件架构/应用架构及以上视角的」,目录是另一个视角的事。 误警二:层数没有标准答案;变体(六边形/洋葱/整洁/垂直切片)的共同内核是 「核心不认得外部世界」——输入输出都只经端口/接口,日志、监控、 表现全是挂在外面的 adapter37。
SOA 与微服务的分界再钉一遍: SOA 服务间共享数据库;微服务为 「可独立部署」打破共享库的习惯——边界干净了,但每个服务要自备持久化, 运维复杂度直线上升。书里那两个「不必」也很实用:事件总线不必有 (连部分服务也行)、UI 不必给人看(API 也是 UI,合并同类 UI 是常见做法)38。
事件驱动的谱系(从 1 行循环到分布式): 最简形态是 GUI 的消息循环 (工具包自带);Web 服务器是中间形态(请求=事件、handler=处理器、 响应又能当新事件);最重形态把 handler 拆成独立模块/应用/机器, 用队列和 mediator 分拣。性能铁律只有一条:事件循环本身永不被慢操作 堵住——长活交给 worker,结果以新事件回环39。
4.2 「架构热」与视角方法论的更多原文细节
三句引文为什么选它们(书里交代了动机):引 Fowler、Gordon、Brown 不是为了凑名人,「这些引文没有一句能帮我们定义架构——意图也不在于定义, 而是让你对『问题有多大』建立直觉,把事情放进视野(perspective)」。 第四句 Brown 的「结构与设计是各利益相关者需求的结果」,是全书视角方法的 支点句:先有 stakeholders 和他们的需求,才谈得上结构40。
假废墟与悬链模型之外,书里对类比的边界还有一句保险: Fowler 的原话 「企业应用不包括汽车燃油喷射」被引来划线——建筑与软件之间没有一一映射, 「软件架构不包括土方工程」;类比是脚手架,用完记得拆41。
「蓝图是架构吗?」的完整推理(圣家堂展览那一段的骨架):设计过程产生了 蓝图、静力模型、施工图、样机……每一件都「描绘并偶尔体现」建筑的某个侧面, 没有一件能独占「架构」之名;同理,软件的代码、部署图、数据模型、 接口契约,各自是架构的某个视角。「架构可以在任意粒度上定义——细到一定程度 就叫 pattern;反过来,某些 pattern 针对整个系统时也叫架构。」这两个词 是孪生的42。
5.8 代码组织视角的更多方案
第 2 章这一视角在第 3 章会长成八种切法的大目录;这里的预告只强调一个分野: 少管你的框架把目录自由留给开发者;约定优于配置的框架给目录赋予意义 (映射 MVC 等模式),「能藏多少藏多少」。两种都对,错的是不明确自己用的是 哪一种43。
6.5 事件驱动架构的主线例子补完
拿本章主线例子(工单从创建到完成)走一遍事件循环:
事件队列里依次躺着:
TicketCreated(42) → StatusChanged(42, CREATED→SELECTED)
→ StatusChanged(42, SELECTED→STARTED) → ...
循环每个周期取一个事件,查注册表找 handler:
TicketCreated → 通知服务:给项目订阅者发「新票」邮件
StatusChanged → 通知服务:给该票订阅者发「状态变更」邮件
没有 handler 的事件 → 忽略,取下一个
慢活(渲染邮件、逐个发送)全部委托 worker,
worker 干完把结果作为新事件丢回队列 —— 循环永不阻塞。
图说:第 8 章的通知队列就是这条循环的分布式版本;
第 12 章的 SSE/WebSocket 则是「把事件直接推给浏览器」的变体。
(事件名为演示编的;循环与 handler 的语义出自原文。)这条线值得现在记住:第 2 章的事件循环、第 8 章的 Redis 队列、第 12 章的 实时推送,是同一件事的三个规模——事件产生、有人订阅、按序送达。
5.9 方法论视角的完整谱系(从结构化编程到敏捷家族)
书里把「方法论」与「编程范式」的分界说成一句话:两者只差野心—— 方法论想把整个开发过程(从启动到交付乃至再启动)都管起来,范式只管 代码怎么写。最老的方法论是结构化编程,它恰好也是范式:自顶向下、 逐层分解,直到每块都平凡可解44。
瀑布为什么像制造业: 分析 → 设计 → 开发 → 测试 → 部署 → 维护, 六个阶段,每个都以前一个完成为前提——这正是工厂流水线的节奏。 它在软件里栽跟头的根子,书里那句比喻一针见血:死守阶段制, 等于把「软」字从软件里抽掉了——软件之为软件,本就在于需求会变、 理解会加深、设计要返工45。
敏捷家族的反应: RAD、XP、Kanban、Scrum 一起登场,共同主张是 「把变化当自然属性、迭代前进、开发是生命周期里永不结束的圆」。 书里特意补了一手「没有颠覆」的证据:看板的列就是瀑布阶段的复活, 「没有一张用户故事能同时处在两列」;工作流照样从左拖到右。 教条的「敏捷 vs 瀑布」对立,在真实的看板面前自动消解46。
5.10 基础设施视角:清单逐项的「谁来在乎」
书里这份清单的每一项,都标注了它背后的关切方——这就是「基础设施 也属于架构」的理由:
| 清单项 | 谁在乎 | 为什么 |
|---|---|---|
| 操作系统 / 文件系统 | 全员 | 一切的地基 |
| 通信层(TCP/IP、HTTP、MQTT) | 开发者 + 运维 | 组件之间怎么说上话 |
| 持久化(关系/嵌入式/NoSQL) | 架构师 + DBA | 数据放哪、怎么活 |
| 版本控制 | 全员 | 协作的地基 |
| 容器化 / 编排 / CI/CD | DevOps | 怎么交付、怎么跑 |
| 第三方组件(Web 服务器、负载均衡、缓存) | 架构师 | 请求怎么进来、怎么分摊 |
| 平台与运行时 | 开发者 | 代码在什么上跑 |
「操作系统、网络、托管与部署模型,决定了开发和运维里『做什么、怎么做』」; 基础设施与架构难画线,因为双方都重度使用定下来的同一批组件47。
5.11 软件架构视角:语言分类学的一次实战
书里给「编程语言」这个决定配了一张分类表,实战用法是拿它当问卷:
- 目标类型:编译 / 解释 / JIT——决定性能量级(第 1 章的 40 倍基准 就是这个轴在起作用);
- 范式:结构化 / 面向对象 / 函数式——决定思维工具箱;
- 内存模型:手动 / 托管——决定有没有 GC 这道税(Rust 属于 「编译 + 手动-ish(所有权)+ 无 GC」这个独特格子);
- 类型系统:静态 / 动态;
- 抽象层:高 / 低;
- 领域:通用 / DSL。
框架与适配器这对词也值得单独记住:框架 = 「现成的、常预配置的 库集合,解决某技术领域最常见的问题」;适配器 = 「让你接上别的软件的 兼容层」;集成库 = 「帮 A 的输出翻译成 B 的输入的库集合」—— 第 6 章换数据库时,ORM 干的就是「适配 + 集成」的活48。
6.6 分层架构的工程细节(这本书后面每一章都在用)
依赖方向为什么只能向下: 层叠架构的全部价值在那几支单向箭头里—— 表现层依赖业务层,业务层依赖持久层,反过来不行。「这不是只有关注点分离, 更是解耦:层间访问受限,依赖被控制成单一方向」——箭头一旦能回头, 层就退化成一锅粥49。
三层各自对外面的态度(书里写得很细):
- 表现层是「应用与外部世界通信的表层」——外部世界不该直接接触任何 其他层,数据的进和出都走这个面;
- 业务层装的是「核心业务,即领域」——它是应用要提供的那件解决方案, 最常见的情况下,它也是表现层与持久层之间的传话人;
- 持久层负责「把数据存成以后能可靠取回的样子」——持久化不一定是数据库, 文件、远程服务都算,这层名指的是职责不是技术50。
四个变体的血缘关系(一张族谱):
分层架构(三层)
├─ 六边形:核心与外部世界之间只许走「端口 + 适配器」
│ 表现、日志、监控都是 adapter,核心不认得 HTTP
├─ 洋葱:同思路换说法——核心定干净接口,外层去实现
├─ 整洁:四个同心壳——实体(企业业务)→ 用例(应用业务)
│ → 适配器(网关/控制器/展示器)→ 外部(UI、DB、Web)
└─ 垂直切片:按业务把各层「竖着切开」,
这个业务用几层就留几层,不强迫全局统一层数
图说:前三者是同一种思想的三种画法;垂直切片是对「全局分层」的反抗。物理分层 = n-tier: 当逻辑层被拆到不同物理机器(浏览器、应用服务器、 数据库机),就叫 n-tier——「层」管逻辑角色,「tier」管部署位置; 三层架构(two-tier/three-tier)的说法由此而来51。
6.7 SOA、微服务与共享数据库之争
SOA 的保守与微服务的决绝: SOA 把应用切成「职责分明、边界清晰的服务」, 但共享一个数据库——服务是逻辑隔离、物理同库;微服务为了「可独立部署」 这条铁律,连库一起拆——「微服务打破了共享数据库的习惯,因为它们追求 可独立部署」。拆库的代价书里没回避:每个服务要管自己的持久化, 数据一致性从「数据库帮你管」变成「架构师你看着办」52。
拓扑图的两个「不必」(读架构图时的去魅口诀):
- 图里的「事件总线」不是必需品——「可以连部分服务,也可以没有」; 它是画上去的选项,不是欠下的债;
- 图里的「UI」不一定是给人看的界面——「它不必是图形界面,甚至不必是 人用的界面;任何能与微服务交互的 API 都算」。实践中常见做法是合并 归属相同的 UI、下面统一接 API 层53。
视角归属: 这两个模式「更多是系统架构师的视角,而非应用架构师」; 但「所有工程师都必须清楚自己工作在哪种架构里」——这句提醒对跨团队 协作尤其值钱54。
6.8 事件驱动的完整形态谱系
最简形态(一个循环)的四个零件: 事件源(产生)、循环(取和分发)、 handler 注册表(找匹配)、忽略策略(没有 handler 就丢)。「handler 事先 不知道事件何时发生,所以看起来像异步——其实就是一个不停转的循环」55。
进阶形态的三级火箭:
- 进程内: GUI 消息循环(工具包代写)、Web 服务器(请求即事件);
- 线程分离: 「最高效的形态至少把事件循环和处理分到不同线程—— 循环永远不被堵,慢操作委托 worker,结果以新事件回环」;
- 进程/机器间: handler 是整个模块、独立应用或远程服务,事件进队列、 由中介分拣进 channel——这就是第 8 章通知服务和第 12 章实时推送的 共同骨架56。
一条贯通全书的事件线(现在建立,后面不断收回):
第 2 章:事件循环(单进程)
第 8 章:Redis 队列 + fang 调度(多组件、可延迟)
第 12 章:SSE / WebSocket(事件直达浏览器)
——同一个抽象换了三次规模;学一次,用三次。
图说:事件 = 状态变化的通知;订阅 = 谁想听;送达 = 按序、不丢、不扰。6.9 「模式 / 架构 / 风格」的三词之争
工作定义书里给得干脆:模式 = 对常见问题的反复出现的设计解法; 架构 = 以整个系统为目标去应用的模式。配套两点背景:57
- 业内对 style(风格)的用法不一致:Ghidersa 按「解决问题与否」划 (解决问题的叫 pattern,只强化实践的叫 style);Mark Richards 与 Neal Ford 在《Fundamentals of Software Architecture》里把同类清单 归进 style——两派权威口径相反;
- 本书的态度:「别 cling(死抓)术语——我们的定义够接下来几段用了。」
这套「够用就好」的姿态,和第 2 章处理「架构」大词时一模一样: 术语是为了协作,不是为了赢辩论。
3.4 tech stack 定义的完整推理(从字典到选型纪律)
「stack 是草垛」给选型的三条启示(把本义用足): 其一,堆叠的组件 可以贴得很紧——「从草垛底部抽一根换一根」式的替换成本是真实存在的, 别假设 tech stack 里的组件随换随走;其二,数量可以很少——LAMP 四个 字母就是四样,stack 不以长为荣;其三,「成了惯常搭配就算 stack 的一员」—— Linux 不是为 Web 生的,但 routine 用在 Web 上,它就是 LAMP 的 L58。
「先需求后选型」的反面教材(书里一句话版): 「只有当我们挑中的组合 恰好与某个现成方案重合时,才用现成方案」——顺序永远不是「看 stack 好不好」, 而是「我们的需求是什么,然后逐组件评估」。把这两句话抄进团队的选型 模板,能挡住一大半拍脑袋59。
「塑料做的 stack」的两个推论: tech stack 不计其数(换掉任一组件 就是一个新 stack);专业环境里它是逐个组件评估出来的,预打包方案 只配当速写参考。「stack 是 plastic(可塑)的,不是铸铁」——这句原文 的比喻比「灵活」一词精确:可塑意味着要你动手塑,不是免塑60。
4.3 视角方法的元规则(为什么「不找定义」反而是正解)
书里对「架构无法定义」的应对,本身就是一条可以迁移的方法论:
- 承认混乱是结构性的——Fowler 那句「最大的受害者是 architecture」 不是修辞,是行业常态;
- 用视角换取确定性——每个视角内部,词是有明确所指的 (方案设计的「架构」、基础设施的「架构」各说各话,但各自清楚);
- 声明自己的视角再开口——「架构师们乐得不提视角就贴标签; 而视角恰恰决定该怎么解读那句话」;
- 粒度到位就换词——细到实现的叫 pattern,针对整系统的 pattern 升格叫 architecture61。
两个建筑类比的使用纪律: 类比只为「传达直觉」,不为「建立映射」—— 假废墟传达「先有目的」、悬链模型传达「同一物多视角」; 「企业应用不包括汽车燃油喷射」是作者给自己也是给读者的护栏: 类比一过度延伸,就会 derailed(出轨)62。
5.12 视角之间的接缝(谁把什么递给谁)
六个视角不是并列的清单,而是一条流水线;书里散在各节的接缝句收拢如下:63
① 方案设计(业务专家)──术语/构件/关系/行为──► ② 方法论(过程)
│ │
▼ ▼
③ 基础设施(运维)◄──部署模型────────────── ④ 软件架构(构件与框架)
│ │
▼ ▼
⑤ 代码组织(目录)◄──框架隐含的决定────────── ⑥ 模块化(切到哪)- ②→③:方法论定了节奏,基础设施定了跑道;「部署模型决定开发和运维的 做什么、怎么做」;
- ④→⑤:框架「自带架构决定」,约定优于配置的框架还会给目录赋义;
- ①→④:方案设计的概念「可以不以技术面目出现」——代码跟着业务概念走, 换来与利益相关者的共同语言(第 4 章的建模即此道的实践)。
「架构可以在任意粒度定义」的推论: 同一个人上午谈系统架构、下午谈 某个函数的 pattern,两不冲突——「细到实现叫 pattern,面向整系统的 pattern 叫 architecture」;术语跟着粒度走,不跟人走64。
6.10 事件驱动 vs 分层 vs SOA 的一次对照(选型的最后一眼)
| 分层 | SOA/微服务 | 事件驱动 | |
|---|---|---|---|
| 切分依据 | 逻辑角色 | 业务职责(服务) | 状态变化(事件) |
| 依赖方向 | 单向向下 | 服务间显式调用(+可选事件总线) | 发布者与订阅者解耦 |
| 通信 | 进程内调用 | 网络(API) | 队列/事件通道 |
| 顺序保证 | 无涉 | 调用本身有序 | 队列保序(FIFO) |
| 典型故障 | 层间缠死 | 分布式一致性 | 无 handler / 消息积压 |
| 本书落点 | 应用内部骨架 | 第 2 章选型比较 | 第 8 章通知 + 第 12 章推送 |
选型口诀(我们的归纳,依据各节边界): 一个应用内部分工 → 分层; 多个团队/部署单元 → SOA 起步、微服务慎重;「谁该被通知」变得比 「谁调用谁」更要紧时 → 事件驱动65。
8.1 本章与全书的债务登记(许诺-兑现的一次预演)
本章留下的、后面必须兑现的许诺:66
| 许诺 | 兑现处 |
|---|---|
| 「看板列就是瀑布阶段」的方法论讨论 | 第 6 章 TDD/BDD 的流程观 |
| 「框架隐含架构决定;Rust 缺全家桶」 | 第 7–10 章的手工清单 |
| 「事件驱动先记住循环」 | 第 8 章队列、第 12 章 SSE/WS |
| 「换库别锁死,用适配层」 | 第 4 章 ORM、第 11 章 object_store |
| 「打分表防暗箱」 | 第 10 章 Casbin 策略入库的决策背景 |
6.11 「架构 frenzy」的完整收尾:为什么本章配得上「 frenzy」之名
回看全章:它从一个「被用烂的词」出发,却不给定义,而是—— 引三句名人名言建立混乱的直觉 → 用两个建筑类比教会「视角」→ 认领六个视角各管一段 → 摆五种架构各带自己的适用域 → 最后把候选清单(04)摊上桌。「frenzy(狂乱)」在章名里是自嘲: 词义乱成一锅,但你可以有自己的指南针67。
这一章对「编程语言与系统研究」的独到价值(我们的判断): 它示范了一种罕见的写法——不给大词下定义,而是给大词配操作手册。 「架构」「技术栈」「模式」这些词在每一本技术书里都出现,敢承认 「定义不了、也不必定义,只要视角齐全」并把这句话落成六个可执行的 检查项,是工程写作里少有的诚实。
章末的总账(许诺-兑现自查): 本章许诺的后续——「框架版图走一圈 选 Axum」(03/04 兑现)、「SQLite 起步、换库不重写」(第 4 章兑现)、 「事件驱动记住循环」(第 8/12 章兑现)、「打分表用于工单选型」(03 兑现) ——全部兑现,无一拖欠;这份「许诺-兑现」清单也已在 §8.1 登记68。
6.12 分层架构主线例子的逐层状态账(工单 #42 的完整往返)
表现层(Yew 页 / 命令行 / API 端点 —— 三任可换)
收到:小李的「推进到 TESTING」操作
状态:持有 DTO、不做判断,原样转交
↓
业务层(校验 + 规则)
状态机检查:REVIEWING → TESTING 合法?是
角色检查:小李是 Developer,处理阶段可改 —— 放行
副作用决策:写日志、发事件
↓
持久层(SeaORM / SQL)
两行写入:ticket.state = TESTING;ticket_update 日志一条
状态:数据库是唯一落盘的事实
↓
原路返回:持久层 → 业务层(组装结果)→ 表现层(渲染新徽章)
图说:每一层只跟直接下层说话;层内不越权、层间不回头。
——这六行对应原书对三层职责的定义,每一行都能指到原文。为什么这个骨架撑得起后面十章: 第 5 章(分页排序)在表现层与业务层之间 加参数;第 7 章(访问控制)在业务层门口加守卫;第 8 章(通知)在业务层的 副作用上挂事件;第 10 章(缓存)在持久层前加一层快存——改动全落在某一层 的边界上,从不需要推翻三层本身。这就是「分层是最小可用架构」的证据69。
8. 原文地图补充
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 「塑料做的 stack」与逐个组件评估 | Selection of a Tech Stack | text/11-fm-definition-of-a-tech-stack.txt:22(搜「plastic bundle」与「component-by-component」) |
| 方案设计的职责清单 | 同上 | text/12-fm-the-architecture-frenzy.txt:102(搜「solution design」) |
| 瀑布的「软」字批评 | 同上 | text/12-fm-the-architecture-frenzy.txt:157(搜「soft attribute」) |
| 基础设施与架构难画线 | 同上 | text/12-fm-the-architecture-frenzy.txt:166(搜「hard to draw the line」) |
9. 可带走的(补三条)
- 层是逻辑角色,tier 是物理部署——n-tier 是分层架构的物理化,两个词别混。
- 框架 = 预配置的库集合;适配器 = 兼容层;集成库 = A 的输出译成 B 的输入——第 6 章换装时它们各司其职。
- 术语跟着粒度走:细到实现叫 pattern,面向整系统的 pattern 叫 architecture;「够用就好」是处理大词的正解。
10. 深度展开:敏捷家族的四种做法各管什么(原书名单的逐位介绍)
书里在方法论一节点了 RAD、XP、Kanban、Scrum 四个名字,每个都值得 一句话身份照,免得在别处撞见时不认得:70
- RAD(快速应用开发): 敏捷家族的老资格,主张用原型和迭代换 「需求消化速度」——它的遗产是「先做个能摸的再说」;
- XP(极限编程): 把「拥抱变化」落到工程纪律:测试先行(第 6 章 TDD 的源头)、持续集成、结对编程、小步发布——「极限」指的是把 良好实践推到极致;
- Kanban: 可视化工作流 + 在制品上限;看板的列就是瀑布阶段的 复活(原书证据:「没有一张用户故事能同时在两列」);
- Scrum: 固定节奏的迭代(冲刺)+ 三种角色与四种仪式;与 Kanban 的差别在于「承诺驱动」(冲刺目标)对「流驱动」(连续拉卡)。
书里对整族的冷静评价再引一次: 「现实中没有任何方法论被真正丢弃—— 它们演化、合并、复现。」别在方法论之间站队;看懂自家团队的板子和节奏 里住着哪些幽灵,比背诵宣言有用。71
11. 深度展开:「自顶向下 vs 自底向上」的工程形态
这一对方向词贯穿全书:第 2 章切大象(自顶向下)与第 3 章「等结构重复 就抽出来」(自底向上);第 4 章建模先画全景再填实体(顶),workspaces 按职责长出来再合并(底);第 12 章先写整个 compose 文件再微调(顶), CI 从一条流水线长成一个矩阵(底)。两种方向不是方法论之争,是 问题形状之别:需求清晰时从顶,模式未知时从底——这也是原书把两种 都列入视角清单而不偏袒的理由。72
12. 「观察者位置决定所见」的两次示范(本篇的方法论核心)
视角方法的核心命题是「没有视角就没有定义」,本篇给了两次完整示范:73
示范一:圣家堂的悬链模型。 同一座教堂,静力师看到的是倒挂的 沙袋网,施工方看到的是蓝图与脚手架,游客看到的是立面——每件都「是」 教堂的架构,没有一件「独占」架构之名。类比到软件:同一份代码, 开发者看见类型与函数,运维看见进程与端口,PO 看见功能流转—— 架构评审的第一件事不是画泳道图,而是确认在场者各自站在哪。
示范二:方案设计与软件工程的「分辨率」之分。 方案架构师定术语、 构件与关系(业务分辨率);软件架构师定组件、基建与栈(系统分辨率); 工程师在自己那一两个项目里细化(项目分辨率)。三种人说的「架构」 是同一件事在不同缩放级别的样子——「别被职位名称迷惑,两者都与架构 有莫大的关系」。74
一句话收束本篇: 大词不可怕,可怕的是不知道自己站在哪个视角 就用它——「视角决定解读」是本篇送给读者的随身工具。75
13. 本篇卷尾(一句话版)
技术栈是「为某目的常搭配的技术」,架构是「带着视角才存在的结构」, 选型是「先需求、后组件、可打分、无暗箱」——本篇三个词各给了操作定义, 04 篇的候选清单便有了用武之地。这是第 2 章上半场(01–03 拆)交出的 全部家当,也是后面十二章每一次落锤的受力点。76
14. 本篇卷尾补记(视角清单的日常用法)
把六个视角折成一张可贴墙的检查单,每次开会前扫一遍:业务概念定了没 (方案设计)、过程按什么节奏走(方法论)、跑在哪/靠什么存(基础设施)、 构件与框架定了没(软件架构)、目录怎么摆(代码组织)、切到哪一层 (模块化)。十秒钟扫完,缺哪个补哪个——这就是「架构」大词的全部 日常使用。77
15. 三句引文的完整收藏(含出处与使用场景)
| 引文 | 出处 | 什么时候搬出来 |
|---|---|---|
| 「软件行业乐此不疲地拿词来用……最大的受害者之一是 architecture。」 | Martin Fowler,《Patterns of Enterprise Application Architecture》 | 讨论架构定义乱成一团时,先立这道免战牌 |
| 「我暗暗怀疑,架构是被用得最多、被懂得最少的词之一。」 | Ian Gordon,《Essential Software Architecture》 | 团队里有人要「先统一定义再开工」时,用它换视角法 |
| 「architecture 对不同的人意味着完全不同的东西,网上漂着一大堆定义。」 | Simon Brown,《Software Architecture for Developers》 | 引入「认领视角」方法时的开场白 |
| 「结构与设计,无论软件还是建筑,是各利益相关者需求的结果。」 | Simon Brown,《Software Architecture for Web Developers》 | 强调「先有 stakeholders 再有架构」时 |
使用纪律: 引文是开场白不是论据——它们证明的是「混乱存在」, 而不是「哪个视角正确」;论证永远回到六个视角的具体清单上。78
16. 本篇卷尾补记(视角法的迁移)
「认领视角」不只用于架构:谈性能时说「谁的性能、哪个场景」;谈质量时 说「谁的标准、哪个层次」;谈成本时说「谁的时间、谁的机器」。任何大词 都可以先问视角再问定义——这把钥匙是第 2 章送出的最耐用的工具。79
17. 本篇卷尾补记(视角法的最后提醒)
六个视角是检查单,不是流程图——它们不必按顺序走,也允许反复横跳; 唯一的要求是:开口谈「架构」之前,先报出自己的视角。这一句纪律, 比本章任何一个具体定义都耐用。80
16. 本篇卷尾补记(术语卡)
三个词的最后校准:stack(为某目的常搭配的技术,可塑)、architecture (带视角的结构性决定,粒度可粗可细)、pattern(常见问题的反复解法)。 三词一张卡,出门不心虚。81
Footnotes
-
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:22,搜「we first define our requirements」)。原文:「To emphasize, we first define our requirements and then choose a tech stack, not vice versa.」 ↩ -
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:7,搜「haystack」;:10,搜「tightly coupled」)。字典义引自原书脚注所引词典;「从草垛底部抽一根换一根」的比喻见原文:「We can think of it as removing a twig from the bottom of a pile and putting another one in its place」。 ↩ -
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:13,搜「general-purpose operating system」;:16,搜「collection of technologies」)。 ↩ ↩2 -
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:22,搜「plastic bundle」与「component-by-component」)。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:7,搜「delights in taking words」)。引自 Martin Fowler, Patterns of Enterprise Application Architecture。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:16,搜「sneaking suspicion」)。引自 Ian Gordon, Essential Software Architecture。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:25,搜「means many different things」)。引自 Simon Brown, Software Architecture for Developers。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:34,搜「perspective」)。原文:「software architecture cannot be defined without adding a perspective from which we observe the topic」。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:56,搜「romantic ruins」;:59,搜「stakeholders」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:78,搜「statical model」)。「represent the cathedral itself, upside down」及「none of them could exclusively claim to be the architecture」均在同段。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:84,搜「fuel injection」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:102,搜「business logic」与「solution architect」)。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:115,搜「Top-down approach」;:122,搜「slicing the elephant」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:128,搜「consistent collection」;:131,搜「structured programming」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:134,搜「manufacturing and construction」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:157,搜「embracing change」)。「把软字抽掉」的原文是「Sticking to such distinct phases removes the soft attribute from software development」(:157)。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:160,搜「columns on the board」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:166,搜「Operations engineers」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:213,搜「draw the line here」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:219,搜「WordPress」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:285,搜「recurring design solution」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:298,搜「Ghidersa」;:301,搜「Fundamentals of Software Architecture」;:304,搜「cling too much」)。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:295,搜「implied」)。原文:「they come with the architecture decision implied, for they implement a certain pattern」。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:310,搜「half a success」)。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:319,搜「not modular enough」)。 ↩ ↩2 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:331,搜「distinct roles」;:341,搜「directly below」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:360,搜「ports and adapters」;:363,搜「clean interfaces」;:366,搜「four main shells」;:370,搜「bare minimum」)。 ↩ ↩2 ↩3 ↩4 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:389,搜「shared database」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:402,搜「independently deployable」与「not mandatory」)。 ↩ ↩2 ↩3 -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:414,搜「loop that processes events」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:424,搜「separate thread」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:102,搜「domain logic」与「resolutions」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:157,搜「RAD」与「Scrum」)、:160(搜「reappearance」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:166,搜「hard to draw the line」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:219,搜「WordPress」)、:295(搜「implied」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:373,搜「n-tier」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:353,搜「do not have to organize our code」)、:360(搜「ports and adapters」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:402,搜「not mandatory」与「any kind of API」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:414,搜「loop」)、:424(搜「never blocked」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:31,搜「intention」)、:40(搜「stakeholders」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:90,搜「earthworks」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:105,搜「arbitrary granularity」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:310,搜「convention-over-configuration」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:131,搜「paradigms」)、:128(搜「consistent collection」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:157,搜「soft attribute」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:160,搜「No user story can be in two columns」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:166,搜「The operating system chosen」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:271,搜「Frameworks」)、:274(搜「Adapters」)、:277(搜「Integration」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:331,搜「directed in one direction only」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:344,搜「surface level」)、:347(搜「communication layer」)、:350(搜「persisting the data」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:373,搜「n-tier」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:402,搜「break with the habit of using a shared database」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:402,搜「not mandatory」与「any kind of application programming interface」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:405,搜「system architect」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:414,搜「loop that processes events」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:424,搜「separate thread」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:285,搜「recurring design solution」)、:298(搜「Ghidersa」)、:304(搜「cling too much」)。 ↩ -
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:10,搜「removing a twig」)、:13(搜「general-purpose」)。 ↩ -
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:22,搜「quick adaptation」与「component-by-component」)。 ↩ -
出处:「Definition of a tech stack」(
text/11-fm-definition-of-a-tech-stack.txt:22,搜「plastic bundle」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:34,搜「perspective from which we observe」)、:90(搜「generous in putting the architecture sticker」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:81,搜「gets forced and derailed」)、:84(搜「fuel injection」)。 ↩ -
接缝图为我们的整理;各环节原文依据见 §5.1–§5.6 各节引文。 ↩
-
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:105,搜「arbitrary granularity」)。 ↩ -
选型口诀为我们的归纳;三种架构的定义与边界见原书 Architecture examples 三节。 ↩
-
债务登记为我们的全书对账;各兑现点见对应拆解章。 ↩
-
章名解读与全章结构为我们的归纳;引文与视角流程见 §4–§6 各节。 ↩
-
兑现登记见本书
03§5–§7、04§5、06§2–§3、11§3、16§4–§5。 ↩ -
层职责出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:344,搜「Presentation」);各章落点见对应拆解文档。 ↩ -
四名字名单见「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:157,搜「RAD」);各一句话介绍为行业通行常识(补充,不在书里逐位展开)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:160,搜「discarded」)。 ↩ -
形态对照为我们的全书对账;方向定义见
text/12-fm-the-architecture-frenzy.txt:122(搜「slicing the elephant」)。 ↩ -
两次示范分别出自「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:78,搜「statical model」)与:102(搜「resolutions」)。 ↩ -
出处:「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:102,搜「different levels or resolutions」)。 ↩ -
收束句为我们的归纳;视角命题见
text/12-fm-the-architecture-frenzy.txt:34。 ↩ -
卷尾为我们的归纳;三词定义见本篇 §3、§4、§5–§6 各节。 ↩
-
检查单为我们的产品化整理;六视角见本篇 §5。 ↩
-
四条引文均见原书「The architecture frenzy」(
text/12-fm-the-architecture-frenzy.txt:7、:16、:25、:40)。 ↩ -
迁移提醒为我们的产品化建议;视角命题见本篇 §4.3。 ↩
-
提醒为我们的产品化整理;视角命题见本篇 §4.3 与 §12。 ↩
-
校准见本篇 §3、§4.3、§6.9。 ↩