十三Tech
设计取舍

图解 Go 设计模式

用 Go 的接口、组合、函数和并发习惯重新理解经典设计模式,关注模式背后的工程边界。

适合已经写过 Go,希望把设计模式从名词表变成日常设计判断的工程师。

1717/17 已完结最近更新 2026/6/15
阶段目录

按主题段落阅读

文章列表

完整目录

17
01

图解 Go 设计模式 01|单例模式:sync.Once 为什么是 Go 的标准答案

单例是设计模式里被讲得最烂的一个,也是最容易写错的一个。本文聊聊 Go 里为什么 sync.Once 是标准答案,以及更重要的——你真的需要单例吗。

02

图解 Go 设计模式 02|工厂方法:把对象创建逻辑从业务代码里赶出去

工厂方法被讲成「定义接口创建对象」,但这是描述不是理由。本文聊聊 Go 标准库怎么用 driver.Register 把创建逻辑收敛到一处。

03

图解 Go 设计模式 03|建造者模式:当构造函数参数多到没人敢动

建造者被讲成「分步构建复杂对象」,但大多数文章没说清楚什么时候该用。本文聊聊 Go 里 Functional Options 和链式建造者的取舍。

04

图解 Go 设计模式 04|原型模式:复制比新建贵的对象,才值得深拷贝

原型模式被讲成「通过克隆创建对象」,但这个定义在 Go 里几乎没意义——new 一个对象又不贵。本文聊聊原型的真实价值在配置模板、请求骨架等场景。

05

图解 Go 设计模式 05|对象池:sync.Pool 用对是利器,用错是内存泄漏

对象池被讲成「复用对象减少 GC」,但 sync.Pool 的语义比这个微妙得多。本文聊聊什么场景该用对象池,以及 sync.Pool 的常见误用。

06

图解 Go 设计模式 06|适配器:不动旧代码,把接口翻译成你想要的样子

适配器被讲成「让不兼容接口协作」,但这个定义模糊到可以套在任何包装层上。本文聊聊适配器真正解决的是「双方都不能改但必须配合」的场景,以及它和门面、代理的边界。

07

图解 Go 设计模式 07|装饰器:HTTP 中间件背后的洋葱模型

装饰器被讲成「动态叠加功能」,但这个定义套在中间件、责任链、代理上都成立。本文聊聊装饰器的标志特征——洋葱模型,以及它和代理的真实差别。

08

图解 Go 设计模式 08|代理:客户端以为在用真实对象,其实被拦截了

代理被讲成「控制对象访问」,但控制访问有十几种方式。本文聊聊代理的标志特征——透明拦截,以及四种典型代理(虚拟、保护、缓存、远程)的真实场景。

09

图解 Go 设计模式 09|门面:给复杂子系统一个干净入口

门面被讲成「简化复杂系统」,但简化有两种——隐藏 vs 合并。本文聊聊门面模式的标志特征是「多对一合并」,以及它跟适配器、中介者的边界。

10

图解 Go 设计模式 10|组合:让叶子和容器实现同一个接口

组合被讲成「树形结构统一处理」,但树形结构有十几种实现方式。本文聊聊组合模式的标志特征——叶子和容器同接口,以及它跟装饰器、迭代器的边界。

11

图解 Go 设计模式 11|策略模式:你以为在消除 if-else,其实在做算法可替换

策略模式被讲烂了,但绝大多数文章只告诉你「消除 if-else」。这是结果,不是理由。本文聊聊什么时候才真正值得抽策略,以及 map 注册比 switch 强在哪。

12

图解 Go 设计模式 12|责任链:让请求沿链传递,谁能处理谁处理

责任链被讲成「请求沿链传递」,但传递有两种——拒绝型(审批流)和管道型(中间件)。本文聊聊责任链的标志特征——链上节点自己决定是否处理,以及它和策略、装饰器的边界。

13

图解 Go 设计模式 13|观察者:一对多的发布订阅

观察者被讲成「一个对象变化通知多个订阅者」,但通知方式有同步、异步、跨进程三种。本文聊聊观察者的标志特征——单向通知,以及它和责任链、Pub-Sub 的边界。

14

图解 Go 设计模式 14|模板方法:算法骨架固定,步骤可替换

模板方法被讲成「父类定义骨架子类填步骤」,但 Go 没有继承。本文聊聊 Go 里用函数字段实现等效语义的写法,以及它和策略、钩子的边界。

15

图解 Go 设计模式 15|状态:行为随状态切换

状态模式被讲成「行为随状态变」,但状态和策略结构一模一样。本文聊聊状态的标志特征——状态自己切换状态,以及它和策略、责任链的边界。

16

图解 Go 设计模式 16|命令:把请求封装成对象

命令模式被讲成「请求封装成对象」,但封装请求有什么用?本文聊聊命令的标志特征——支持撤销/排队/日志,以及它和策略、责任链的边界。

17

图解 Go 设计模式 17|迭代器:统一遍历,无需暴露内部结构

迭代器被讲成「统一遍历接口」,但 Go 的 for range 已经是迭代器。本文聊聊迭代器的标志特征——隐藏容器内部结构,以及 Go 1.23 range-over-func 带来的语言级支持。