跳转到内容

第六部分 · 可用资源:想深入时看什么

读完这本书,你认识了 23 个 GoF 模式,知道每个模式在 Python 和 TypeScript 里怎么写,也见过它们在真实项目里的样子。想往某个方向继续深入,该去看什么?这一部分按方向列出资源,每个方向先说它解决什么问题、本书讲到了哪一步,再列几项值得花时间的资源,最后一句“先看哪一个”,给只想挑一样的人。

这里只列经过时间检验、或者本书写作时核对过的资源,不追求全。书名给出原名,有通行中译本名的同时给出中译本名;中译本名拿不准的,只写原名,不猜。网址都在 2026 年 10 月打开核对过。没有网址的条目是纸质书,请到书店或图书馆查找。

本书是从场景出发讲模式的:先有一段直觉写法,再来一条新需求,看它在哪里吃力。原著的写法相反,先给模式的定义和结构,再讲怎么用。两种讲法互补,各读一遍,印象会深很多。

  • Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides《Design Patterns: Elements of Reusable Object-Oriented Software》(1994),中译本《设计模式:可复用面向对象软件的基础》。四位作者常被称为 GoF(Gang of Four,四人组),本书的 23 个模式就是这本书收的 23 个。原书的案例用 C++ 和 Smalltalk,今天读来有些旧,但每个模式的“适用性”“结构”“参与者”“效果”几节都按固定格式写,查某个模式的适用条件和参与者时可以当参考手册用。本书各章 N.5 的参与者表,用的是它的参与者名称。
  • Eric Freeman、Elisabeth Robson《Head First Design Patterns》,中译本《Head First 设计模式》。图多、口语化,适合入门,Java 示例。如果你觉得原著太干,先读它再回到原著。
  • Refactoring Guru 中文站(refactoringguru.cn/design-patterns)。用插图和类比讲解经典模式,中文翻译完整,示例代码的语言列表里有 Python 和 TypeScript。适合视觉型读者,也适合在忘了某个模式的结构时快速翻一眼。英文版有单独的 Python 目录(refactoring.guru/design-patterns/python)。注意它按 22 个模式组织,和 GoF 的 23 个有一个出入,它没有收解释器,见本书第 27 章。
  • Brandon Rhodes《Python Design Patterns》(python-patterns.guide)。一位 Python 老手写的在线指南,讲哪些 GoF 模式在 Python 里需要、哪些被语言特性取代,还收了 Python 特有的写法(如哨兵对象)。它和本书第 29 章“现代语言里的模式”问的是同一个问题,答案可以对照着读。作者说明这个站点还在持续更新,覆盖的模式并不齐全。

先看哪一个:只想补一本,读原著 GoF;觉得原著难啃,先读《Head First 设计模式》;想要随手能查的网页,用 Refactoring Guru。

模式是重构的目标,不是起点。这是本书第 30 章最后一节的看法,也是《重构》一书第 60 章的主题。

  • 本系列《重构》(多练网,iduolian.com/refactoring)。和本书配套,61 个重构手法,同样是 Python 和 TypeScript 双语。第 60 章”从重构到设计模式“讲怎样用一系列小步骤把代码推向某个模式,也讲怎样推离,是本书各章”该不该用“那一节的实操版。
  • Martin Fowler《Refactoring: Improving the Design of Existing Code》第 2 版,中译本《重构:改善既有代码的设计(第 2 版)》。重构手法的原典。读它的时候,注意哪些手法的终点恰好是某个模式,比如“以多态取代条件表达式”通向策略和状态,“引入特例”通向空对象。
  • Joshua Kerievsky《Refactoring to Patterns》,中译本《重构与模式》。专门讲怎样一步步重构到模式,每个“向模式重构”都有完整的步骤和案例。它的例子用 Java,思路与语言无关。

先看哪一个:本系列《重构》,先把“从一段能跑的代码出发”的思路练熟,再回头看模式,会觉得顺。

GoF 的模式是类与对象这个尺度的。往上一层,是分层、领域模型、数据访问、事务边界这些整个系统的结构。第 30 章只给了六种模式的导览,这个方向把它们展开。

  • Martin Fowler《Patterns of Enterprise Application Architecture》(2003),中译本《企业应用架构模式》。第 30 章的仓储、值对象、MVC 在这本书里都有条目。讲的是业务系统里反复出现的结构:领域模型、数据映射、工作单元、服务层。Fowler 在网站上放了一份完整的模式目录(martinfowler.com/eaaCatalog),按领域逻辑、数据源、表现层等分类,每个模式有简短摘要和链接,适合先浏览,找到感兴趣的再读书里对应章节。
  • Eric Evans《Domain-Driven Design: Tackling Complexity in the Heart of Software》(2004),中译本《领域驱动设计:软件核心复杂性应对之道》。第 30 章的仓储、值对象在这本书里有更完整的上下文:它们怎样和实体、聚合、限界上下文配合。Evans 本人在网上放了一份免费的《DDD Reference》(domainlanguage.com/ddd/reference),把全书的定义和模式浓缩成摘要,采用 Creative Commons Attribution 4.0 许可,适合读过书以后当速查。
  • Vaughn Vernon《Implementing Domain-Driven Design》,中译本《实现领域驱动设计》。Evans 那本偏概念,这本偏落地:怎样把聚合、仓储、领域事件写成代码。篇幅大,建议当参考书,按需翻阅。
  • Harry Percival、Bob Gregory《Architecture Patterns with Python》。用 Python 把仓储、工作单元、服务层、事件驱动这些模式串成一个完整的小项目,和本书的语言一致。本书没有核对它的网址和中译本情况,需要时请自行查找。

先看哪一个:不确定从哪里开始,浏览 Fowler 的在线目录,就能先建立一张地图;然后挑《企业应用架构模式》里和手头项目最相关的几章细读。

第 29 章的结论是:语言越表达得出“把函数当值传”“用结构而不是继承来匹配类型”,有些模式就越轻。想把这一点吃透,读语言本身的资料。

  • Python 语言参考的数据模型一章(docs.python.org/3/reference/datamodel.html)。特殊方法 __getattr__、__iter__、__call__、__enter__ 等都在这里,是装饰器、代理、迭代器、命令这些模式在 Python 里变轻的根源。
  • PEP 544:Protocols,结构化子类型(peps.python.org/pep-0544)。Python 版“按形状匹配接口”的提案原文,本书里 Protocol 的用法出自这里。它还讲了 isinstance 检查要显式加 @runtime_checkable 才能用。
  • TypeScript Handbook(typescriptlang.org/docs/handbook/intro.html)。官方手册,按读者背景给出入口(新手、JS 程序员、Java/C# 程序员、函数式程序员)。联合类型、泛型、结构类型这些,本书用到的 TS 特性都在这里。
  • Luciano Ramalho《Fluent Python》,中译本《流畅的 Python》。逐章讲 Python 的数据模型、迭代器、生成器、装饰器、协议,每章都有可运行的例子。读完你会更清楚什么时候该用类、什么时候一个函数就够。
  • Dan Vanderkam《Effective TypeScript》。TS 版的同类书,讲类型设计和常见陷阱。
  • 本系列《程序设计语言特性》(多练网)。按特性而不是按语言组织,讲同一个特性在 Python、TypeScript 和其他语言里的异同,以及背后的实现和代价。本书第 29 章说的“语言特性让一些模式变轻”,在它那里有按特性展开的完整版本。

先看哪一个:写 Python 的读数据模型一章,写 TypeScript 的读 Handbook;想要对比视角,读《程序设计语言特性》。

模式最好的老师是真实项目。本书的真实例子都取自下面这些项目,你可以带着书里的章节去它们的源码里找对应的位置。源码一直在变,文件的位置和内部写法以你打开时的版本为准,这里只给入口,不保证细节。

  • Django(github.com/django/django)。第 12 章的代理看 django/utils/functional.py,里面的 LazyObject 和 SimpleLazyObject 就是延迟创建的代理,request.user 用的就是它。第 18 章的观察者看 django/dispatch/dispatcher.py 里的 Signal,官方文档的“信号”一节(docs.djangoproject.com/en/stable/topics/signals)讲怎样连接和发送,文末还有一句提醒:信号会让代码难读,能直接调用函数时优先直接调用。第 17 章的密码哈希器也在 Django 里。
  • CPython 标准库(github.com/python/cpython,标准库在 Lib 目录)。第 15 章的小整数缓存和字符串驻留是 CPython 解释器自己用的享元。第 26 章的访问者可以对照 ast 模块,官方文档(docs.python.org/3/library/ast.html)里 NodeVisitor 通过 visit_类名 找方法、找不到就调 generic_visit,还特别说明要修改节点应该用 NodeTransformer。想读解释器本身,从 Python 开发者指南(devguide.python.org)的内部机制部分入手。
  • Express(github.com/expressjs/express)。第 23 章的责任链和第 30 章的中间件管道,入口在 lib/application.js,里面有 app.use(注册中间件)和 app.handle(把请求送进管道)。
  • Redux(github.com/reduxjs/redux,源码在 src)。第 30 章的中间件管道对应 src/applyMiddleware.ts,它借助另一个文件里的 compose 把中间件串起来。官方教程的 Store 一节(redux.js.org/tutorials/fundamentals/part-4-store)有 applyMiddleware 的用法和三层嵌套函数的写法,适合先读。
  • Babel(github.com/babel/babel,这是个多包仓库,各包在 packages 目录)。第 26 章的访问者例子来自它的插件机制。写插件前先读 Babel 插件手册,其中文版(github.com/jamiebuilds/babel-handbook)开头就把访问者说成“用于 AST 遍历的跨语言的模式”,还讲了进入和退出两个时机。
  • Passport.js(passportjs.org)。第 17 章提到它把各种登录方式叫作 strategy,官网称有五百多种。翻一下它的策略列表,就能体会策略模式让“换一种登录方式”变得多轻。

读源码的方法:不要从头读起。带着一个问题进去,比如“请求是怎么一层层传到视图函数的”,先找入口函数,顺着调用走两三层就够了。对应章节里的简化版代码是你的地图,真实代码比它多出来的部分,多半是线程安全、错误处理和兼容旧版本,把它们暂时当成噪声。

先看哪一个:Django 的 functional.py,一个文件、一个概念,代理的味道最清楚;读完再去 Redux 的 applyMiddleware.ts,它很短。

想系统地往下走,而不只是挑一本:先选一个自己熟的项目,对着第 28 章的选择表找出里面有哪些模式;然后读 GoF 原著或 Refactoring Guru 补全各模式的原始表述;接着读本系列《重构》,练习怎样安全地向模式迈进;工作里碰到业务系统的分层问题,转到 Fowler 的在线目录和 Evans 的《DDD Reference》。语言方面的资料可以随时穿插。

  • 想看原著的完整表述,读 GoF;想要图解,看 Refactoring Guru 中文站;想看 Python 视角,读 Brandon Rhodes 的在线指南。
  • 模式是重构的目标,读本系列《重构》和 Kerievsky 的《重构与模式》。
  • 往上一个尺度,读 Fowler 的《企业应用架构模式》(在线目录先看)和 Evans 的《领域驱动设计》。
  • 语言特性决定模式轻重:Python 看数据模型和 PEP 544,TypeScript 看 Handbook,想对比看《程序设计语言特性》。
  • 读源码带着问题进去,从 Django 的 LazyObject 和 Redux 的 applyMiddleware 开始。