跳转至

技术栈是什么,架构从哪些视角看

这一章(及紧随其后的 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. 作者的判断与证据(分开标)

有出处的:

  • Fowler、Gordon、Brown 三句「架构定义混乱」的引文,均有书名567;
  • 「框架隐含架构决定」是业内通行判断23;
  • 微服务不共享数据库、事件总线非必须,是架构文献的常见口径29。

作者自己的评估:

  • 「从视角看架构」这个应对策略本身是作者(及他引的 Simon Brown)的取舍,不是行业标准方法;
  • 「Rust 缺全家桶框架所以架构决定都要自己做」是把第 1 章短板推演到选型层面的作者推论;
  • 「敏捷只是给瀑布松绑」是对看板列的观察性解读。

8. 边界与局限

  • 术语口径不统一: 作者自己承认 architecture style 与 pattern 的划界在业内有两派 相反说法,本书的工作定义够用而已22——出门撞见别的口径,不必惊讶。
  • 架构示例是导览不是手册: 每种架构一节,够做选型判断,不够落地实施; 微服务的分布式一致性(CAP、Saga 等)要到第 2 章后半(04)和第 10 章才展开。
  • 视角清单是「最常见」而非「完备」: 安全架构、数据架构等视角本书未单列, 散在各章(第 7 章讲访问控制、第 10 章讲缓存,其实就是那两个视角的展开)。

9. 可带走的

  1. 技术栈的正确定义: 一组为某目的经常搭配使用的技术;先需求、后选型, 顺序反过来就是拍脑袋。
  2. 「架构」没有唯一定义,但有视角: 方案设计(业务概念)、方法论(过程组织)、 基础设施(跑在哪)、软件架构(构件与框架)、代码组织(目录)、模块化(切到哪)—— 一次完整想清,六件事各答一个阶段的问题。
  3. 方法论不是教义: 瀑布的死穴是「阶段封死」,敏捷的解法是给阶段松绑 (看板的列就是瀑布阶段的复活)。
  4. 分层三层是最小可用架构: 表现 / 业务 / 持久,单向依赖;六边形、洋葱、整洁、 垂直切片都是它的变体——共同点是「核心不认得外部世界」。
  5. 微服务 = SOA − 共享数据库 + 独立部署; 代价是运维复杂度;教学项目和中小团队, 好模块的单体是更诚实的起点。
  6. 事件驱动最简形态就是一个循环: 取事件 → 找 handler → 递过去;高性能的关键是 循环与处理分线程,循环永不堵。
  7. 挑框架 = 买它隐含的架构决定: 全家桶帮你预做的决定,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。

进阶形态的三级火箭:

  1. 进程内: GUI 消息循环(工具包代写)、Web 服务器(请求即事件);
  2. 线程分离: 「最高效的形态至少把事件循环和处理分到不同线程—— 循环永远不被堵,慢操作委托 worker,结果以新事件回环」;
  3. 进程/机器间: 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 视角方法的元规则(为什么「不找定义」反而是正解)

书里对「架构无法定义」的应对,本身就是一条可以迁移的方法论:

  1. 承认混乱是结构性的——Fowler 那句「最大的受害者是 architecture」 不是修辞,是行业常态;
  2. 用视角换取确定性——每个视角内部,词是有明确所指的 (方案设计的「架构」、基础设施的「架构」各说各话,但各自清楚);
  3. 声明自己的视角再开口——「架构师们乐得不提视角就贴标签; 而视角恰恰决定该怎么解读那句话」;
  4. 粒度到位就换词——细到实现的叫 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. 可带走的(补三条)

  1. 层是逻辑角色,tier 是物理部署——n-tier 是分层架构的物理化,两个词别混。
  2. 框架 = 预配置的库集合;适配器 = 兼容层;集成库 = A 的输出译成 B 的输入——第 6 章换装时它们各司其职。
  3. 术语跟着粒度走:细到实现叫 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


  1. 出处:「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.」 ↩

  2. 出处:「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」。 ↩

  3. 出处:「Definition of a tech stack」(text/11-fm-definition-of-a-tech-stack.txt:13,搜「general-purpose operating system」;:16,搜「collection of technologies」)。 ↩↩

  4. 出处:「Definition of a tech stack」(text/11-fm-definition-of-a-tech-stack.txt:22,搜「plastic bundle」与「component-by-component」)。 ↩↩

  5. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:7,搜「delights in taking words」)。引自 Martin Fowler, Patterns of Enterprise Application Architecture。 ↩↩

  6. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:16,搜「sneaking suspicion」)。引自 Ian Gordon, Essential Software Architecture。 ↩↩

  7. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:25,搜「means many different things」)。引自 Simon Brown, Software Architecture for Developers。 ↩↩

  8. 出处:「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」。 ↩

  9. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:56,搜「romantic ruins」;:59,搜「stakeholders」)。 ↩

  10. 出处:「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」均在同段。 ↩

  11. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:84,搜「fuel injection」)。 ↩

  12. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:102,搜「business logic」与「solution architect」)。 ↩↩

  13. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:115,搜「Top-down approach」;:122,搜「slicing the elephant」)。 ↩

  14. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:128,搜「consistent collection」;:131,搜「structured programming」)。 ↩

  15. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:134,搜「manufacturing and construction」)。 ↩

  16. 出处:「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)。 ↩↩

  17. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:160,搜「columns on the board」)。 ↩

  18. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:166,搜「Operations engineers」)。 ↩

  19. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:213,搜「draw the line here」)。 ↩

  20. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:219,搜「WordPress」)。 ↩

  21. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:285,搜「recurring design solution」)。 ↩

  22. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:298,搜「Ghidersa」;:301,搜「Fundamentals of Software Architecture」;:304,搜「cling too much」)。 ↩↩

  23. 出处:「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」。 ↩↩

  24. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:310,搜「half a success」)。 ↩↩

  25. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:319,搜「not modular enough」)。 ↩↩

  26. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:331,搜「distinct roles」;:341,搜「directly below」)。 ↩

  27. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:360,搜「ports and adapters」;:363,搜「clean interfaces」;:366,搜「four main shells」;:370,搜「bare minimum」)。 ↩↩↩↩

  28. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:389,搜「shared database」)。 ↩

  29. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:402,搜「independently deployable」与「not mandatory」)。 ↩↩↩

  30. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:414,搜「loop that processes events」)。 ↩

  31. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:424,搜「separate thread」)。 ↩

  32. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:102,搜「domain logic」与「resolutions」)。 ↩

  33. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:157,搜「RAD」与「Scrum」)、:160(搜「reappearance」)。 ↩

  34. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:166,搜「hard to draw the line」)。 ↩

  35. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:219,搜「WordPress」)、:295(搜「implied」)。 ↩

  36. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:373,搜「n-tier」)。 ↩

  37. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:353,搜「do not have to organize our code」)、:360(搜「ports and adapters」)。 ↩

  38. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:402,搜「not mandatory」与「any kind of API」)。 ↩

  39. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:414,搜「loop」)、:424(搜「never blocked」)。 ↩

  40. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:31,搜「intention」)、:40(搜「stakeholders」)。 ↩

  41. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:90,搜「earthworks」)。 ↩

  42. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:105,搜「arbitrary granularity」)。 ↩

  43. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:310,搜「convention-over-configuration」)。 ↩

  44. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:131,搜「paradigms」)、:128(搜「consistent collection」)。 ↩

  45. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:157,搜「soft attribute」)。 ↩

  46. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:160,搜「No user story can be in two columns」)。 ↩

  47. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:166,搜「The operating system chosen」)。 ↩

  48. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:271,搜「Frameworks」)、:274(搜「Adapters」)、:277(搜「Integration」)。 ↩

  49. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:331,搜「directed in one direction only」)。 ↩

  50. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:344,搜「surface level」)、:347(搜「communication layer」)、:350(搜「persisting the data」)。 ↩

  51. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:373,搜「n-tier」)。 ↩

  52. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:402,搜「break with the habit of using a shared database」)。 ↩

  53. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:402,搜「not mandatory」与「any kind of application programming interface」)。 ↩

  54. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:405,搜「system architect」)。 ↩

  55. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:414,搜「loop that processes events」)。 ↩

  56. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:424,搜「separate thread」)。 ↩

  57. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:285,搜「recurring design solution」)、:298(搜「Ghidersa」)、:304(搜「cling too much」)。 ↩

  58. 出处:「Definition of a tech stack」(text/11-fm-definition-of-a-tech-stack.txt:10,搜「removing a twig」)、:13(搜「general-purpose」)。 ↩

  59. 出处:「Definition of a tech stack」(text/11-fm-definition-of-a-tech-stack.txt:22,搜「quick adaptation」与「component-by-component」)。 ↩

  60. 出处:「Definition of a tech stack」(text/11-fm-definition-of-a-tech-stack.txt:22,搜「plastic bundle」)。 ↩

  61. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:34,搜「perspective from which we observe」)、:90(搜「generous in putting the architecture sticker」)。 ↩

  62. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:81,搜「gets forced and derailed」)、:84(搜「fuel injection」)。 ↩

  63. 接缝图为我们的整理;各环节原文依据见 §5.1–§5.6 各节引文。 ↩

  64. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:105,搜「arbitrary granularity」)。 ↩

  65. 选型口诀为我们的归纳;三种架构的定义与边界见原书 Architecture examples 三节。 ↩

  66. 债务登记为我们的全书对账;各兑现点见对应拆解章。 ↩

  67. 章名解读与全章结构为我们的归纳;引文与视角流程见 §4–§6 各节。 ↩

  68. 兑现登记见本书 03 §5–§7、04 §5、06 §2–§3、11 §3、16 §4–§5。 ↩

  69. 层职责出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:344,搜「Presentation」);各章落点见对应拆解文档。 ↩

  70. 四名字名单见「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:157,搜「RAD」);各一句话介绍为行业通行常识(补充,不在书里逐位展开)。 ↩

  71. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:160,搜「discarded」)。 ↩

  72. 形态对照为我们的全书对账;方向定义见 text/12-fm-the-architecture-frenzy.txt:122(搜「slicing the elephant」)。 ↩

  73. 两次示范分别出自「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:78,搜「statical model」)与 :102(搜「resolutions」)。 ↩

  74. 出处:「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:102,搜「different levels or resolutions」)。 ↩

  75. 收束句为我们的归纳;视角命题见 text/12-fm-the-architecture-frenzy.txt:34。 ↩

  76. 卷尾为我们的归纳;三词定义见本篇 §3、§4、§5–§6 各节。 ↩

  77. 检查单为我们的产品化整理;六视角见本篇 §5。 ↩

  78. 四条引文均见原书「The architecture frenzy」(text/12-fm-the-architecture-frenzy.txt:7、:16、:25、:40)。 ↩

  79. 迁移提醒为我们的产品化建议;视角命题见本篇 §4.3。 ↩

  80. 提醒为我们的产品化整理;视角命题见本篇 §4.3 与 §12。 ↩

  81. 校准见本篇 §3、§4.3、§6.9。 ↩