GoF:模式
如果你是 Go 开发者,学习 23(GoF)设计模式时,最容易踩的坑是:
背定义
背 UML
硬套模式
最后:
- 看懂了例子
- 真实项目不会用
- 甚至开始“模式滥用”
而 Go 语言本身:
- interface 很轻
- 组合优于继承
- first-class function
- goroutine/channel
导致:
Go 里的设计模式和 Java/C++ 的味道完全不同。
所以:
你真正应该学习的是:
“设计问题” 与 “Go 风格解法”
而不是:
“死记模式模板”
一、先纠正一个概念
严格来说:
GoF 是:
23 个设计模式
不是 24 个。
分类:
| 类别 | 数量 |
|---|---|
| 创建型 | 5 |
| 结构型 | 7 |
| 行为型 | 11 |
总计:
5 + 7 + 11 = 23
二、Go 开发者应该怎么学?
我建议:
不按 GoF 顺序学
而是:
按“真实工程价值”学
因为:
很多模式:
在 Go 里:
几乎:
已经被语言特性替代
例如:
- Iterator
- Command
- Visitor(部分)
- Abstract Factory(部分)
而:
有些模式:
在 Go / 云原生里:
无处不在
例如:
- Adapter
- Decorator
- Strategy
- Factory
- Observer
- Proxy
三、Go 开发者最应该优先掌握的模式
这是我建议的学习优先级。
第一层:必须掌握(天天都在用)
这些:
你每天都在写
即使你没意识到。
1. Factory(工厂)
解决:
对象创建复杂
Go 中:
func NewClient() *Client
其实就是工厂。
你最近接触的:
- APISIX
- Kubernetes
- OpenTelemetry
全部大量使用。
2. Strategy(策略)
解决:
算法/行为切换
Go 特别适合。
例如:
type Compressor interface {
Compress([]byte)
}
不同实现:
- gzip
- zstd
- snappy
Kubernetes scheduler:
本质:
Strategy Engine
3. Adapter(适配器)
解决:
接口不兼容
Go 云原生生态:
到处都是 Adapter
例如:
- CSI
- CNI
- CRI
- database/sql driver
4. Decorator(装饰器)
解决:
动态增强行为
Go 最经典:
io.Reader
还有:
HTTP Middleware
你做 Gateway:
这个极其重要。
5. Observer(观察者)
解决:
事件通知
Go:
特别适合:
- channel
- pub/sub
- event bus
Kubernetes Controller:
本质:
Observer
6. Proxy(代理)
解决:
控制访问
例如:
- RPC proxy
- APISIX
- Envoy
- sidecar
你现在做的领域:
核心模式之一。
第二层:非常重要(架构层)
7. Composite(组合)
解决:
树结构统一处理
例如:
- AST
- Kubernetes 资源树
- UI tree
8. Command(命令)
解决:
行为对象化
适合:
- Workflow
- Job Queue
- CQRS
- Argo Workflow
9. Mediator(中介者)
解决:
复杂对象协作
例如:
- Controller
- Event Router
- Orchestrator
10. State(状态)
解决:
状态驱动行为
Kubernetes reconciliation:
大量使用。
11. Template Method(模板方法)
Go 里少一些。
因为:
Go:
更偏:
组合 + interface
而不是:
继承
但:
Operator Framework:
有时会出现。
第三层:需要理解,但 Go 中不一定常用
12. Abstract Factory
Go 里:
很多时候:
interface + config
就够了。
13. Builder
Go:
大量使用:
WithXXX()
函数式 option。
实际上:
替代了传统 Builder。
14. Singleton
Go:
很少需要真正 Singleton。
通常:
sync.Once
15. Iterator
Go:
天然:
for range
16. Visitor
Go 不适合 Visitor。
因为:
缺少 method overloading。
四、Go 里最重要的不是“模式”
而是:
组合(Composition)
这是 Go 哲学核心。
Go 的很多模式:
都会:
“去类化”
例如:
Java:
class Decorator extends Component
Go:
直接:
type LoggingReader struct {
r io.Reader
}
所以:
你会发现:
Go 模式更“朴素”
但:
更实用。
五、真正要理解的是“设计压力”
这是最关键的学习方法。
不要问:
“这个代码属于什么模式?”
而要问:
“这个代码在解决什么设计压力?”
例如:
Factory
压力:
创建复杂
Adapter
压力:
接口不兼容
Decorator
压力:
不想继承爆炸
Observer
压力:
状态变化需要通知
Mediator
压力:
对象之间耦合失控
State
压力:
if else 状态机失控
六、真正适合 Go 的学习路线(推荐)
第一阶段(最重要)
先学:
- Factory
- Strategy
- Adapter
- Decorator
- Observer
目标:
能看懂云原生源码。
第二阶段
学:
- Proxy
- Composite
- Command
- Mediator
- State
目标:
能做中大型架构。
第三阶段
再学:
- Builder
- Visitor
- Template
- Chain of Responsibility
目标:
提高抽象能力。
七、真正适合 Go 的学习方式
不要:
看 UML
背定义
而是:
“找真实源码”
这是最有效的。
八、推荐你分析的 Go 项目(非常重要)
1. Kubernetes
能学到:
- Observer
- State
- Strategy
- Factory
- Mediator
2. APISIX
能学到:
- Proxy
- Decorator
- Chain
- Adapter
3. Go stdlib
特别:
- io
- net/http
- database/sql
是设计模式宝库。
九、Go 里最经典的模式案例
io.Reader
这是:
Go 设计精华
里面:
同时包含:
- Decorator
- Adapter
- Strategy
例如:
gzip.NewReader(
bufio.NewReader(file),
)
就是:
Decorator Chain
十、你真正应该达到的水平
不是:
“我知道 23 个模式”
而是:
“我能识别系统中的设计压力”
并:
用最简单的方法解耦。
十一、一个非常重要的现实
很多 Go 高手:
从不提:
“这是 xx 模式”
但:
他们写的代码:
到处都是模式思想。
因为:
模式本质上是经验总结
不是:
教条。
十二、最后给你一个真正适合 Go 开发者的模式理解公式
设计模式 =
特定设计压力
+
经典解耦方案
而 Go:
更强调:
“简单实现思想”
而不是: