“现在还需要学习设计模式吗?”这个问题在开发者社区中经常出现。
一方说“这是基本功,必须掌握”,另一方说“现在的语言已经让一半模式变得不必要”。双方都有道理,所以反而更加困惑。
先说结论:设计模式非常值得学习。但从“应用模式”本身成为目的的那一刻起,它反而会变成破坏代码的捷径。
本文将依次说明设计模式为什么必要,以及为什么不能盲目迷信。
什么是设计模式
设计模式简单来说就是解决反复出现的设计问题的经过验证的方案目录。
起点是 GoF(Gang of Four)在 1994 年的《Design Patterns》中整理出 23 种模式。Singleton、Factory、Observer、Strategy 等名称都源自这本书。
重要的是,这些模式并不是某个人凭空发明的。开发者观察到无数项目中有人用相似方式解决类似问题,然后为这些做法命名并整理成目录。
因此,设计模式的本质与其说是“新技术”,不如说更接近“整理过的经验”。
为什么需要 1 — 团队的公共词汇
设计模式最大的实际价值不在代码,而在沟通。
与其解释“这个类只保留一个实例,让它可以全局访问,并把初始化推迟到第一次访问”,不如一句“用 Singleton 吧”就能说清楚。
想想代码审查中一句“这里用 Observer 模式不是更好吗?”包含了多少信息。模式名称是一种压缩率极高的语言。
不了解这套词汇,阅读团队对话、技术文档和开源代码注释的速度都会变慢。技术面试不断询问设计模式,原因也在这里。
为什么需要 2 — 阅读框架的钥匙
我们每天使用的框架,本来就是设计模式的集合。
- iOS 的
UITableViewDelegate是Delegate 模式 NotificationCenter而 Combine 的 publisher 是Observer 模式- SwiftUI 的
View协议组合接近Composite 模式 URLSession.shared是Singleton
了解模式后,即使第一次看到框架 API,也能反向读出设计意图:“原来是这种结构。”你不只是读文档更快,还能预测文档中没有写出的部分。
为什么需要 3 — 复用经过验证的方案
从头思考并解决同一个问题,和从经过数十年打磨的方案出发,起点并不相同。
例如,“对象创建逻辑散落各处,每次修改都会遗漏”是 Factory 模式已经处理过的问题;“状态每次变化都要更新多个界面”则是 Observer 模式已经处理过的问题。
模式整理的不只是方案,还包括该方案的权衡。“Singleton 会引入全局状态,因此让测试变得困难”之类的副作用清单也是模式的一部分。就像地图上标出了前人踩过的地雷位置。
但为什么不能盲目迷信?
看到这里,设计模式似乎无所不能。问题往往发生在“刚学会模式之后”。
拿着锤子时,所有东西看起来都像钉子
学会模式后,容易想把它应用到任何地方,这就是著名的**黄金锤(golden hammer)**陷阱。
给只读取一个配置值的代码套上 Abstract Factory,为只有两个分支的逻辑引入 Strategy 模式,把一个类就能完成的工作拆成 3 个接口和 4 个实现类。
模式是用来降低复杂度的工具,但用在不够复杂的问题上时,模式本身就会成为新的复杂度。如果第一次看代码的人必须跳过 6 个文件才能找到实际逻辑,那不是设计,而是迷宫。
语言发展后,模式会消失
GoF 的 23 种模式是以 1994 年的 C++ 和 Smalltalk 为前提整理的,其中许多已经被语言特性吸收。
// 1994年代:Strategy 模式 — 协议 + 实现类
protocol SortStrategy {
func sort(_ numbers: [Int]) -> [Int]
}
final class AscendingSort: SortStrategy {
func sort(_ numbers: [Int]) -> [Int] { numbers.sorted(by: <) }
}
// 如今 Swift: 只需一个闭包就能达到同样目的
let sorted = numbers.sorted(by: >)
在可以将函数作为值传递的语言中,大多数 Strategy 和 Command 模式一行闭包就能完成。Swift 的enum、值类型和协议默认实现,也能在语法层面解决过去需要用模式处理的问题。
也可以把模式看作“语言尚不能完成的事情,由人用结构补足”。因此,如果把模式列表当成跨时代不变的答案来背诵,就会用几十年前的方式解决语言已经解决的问题。
当模式成为目的
最危险的信号是,设计讨论从“该如何解决这个问题”变成了“该使用哪个模式”。
模式更像解决问题时抵达的终点,而不是起点。重构文献也建议:“不要一开始就套用模式,而要等代码受到朝那个方向演进的压力时,再向模式重构。”
那么,应该如何使用?
总结来说,平衡点如下。
学习时,先看问题,再看方案。 必须记住每种模式是在“什么情况下”出现的,才能在情况不符时选择不用。学习模式有一半是在学习“什么时候不该使用”。
应用时,从最简单的代码开始。 当重复出现 3 次、确实收到变更需求、当前结构开始难以承受时,再重构为模式也不迟。为了未来的灵活性而在今天购买复杂度,大多数时候都是亏本交易。
阅读时,积极利用它们。 阅读他人的代码、框架和开源项目时,模式知识是没有副作用的纯收益。盲目迷信的风险出现在“使用时”,而不是“阅读时”。
总结
- 设计模式是解决重复设计问题的经过验证的方案目录,是观察的产物,而不是发明。
- 必要原因:团队的公共词汇、阅读框架设计的钥匙,以及连权衡都整理好的经过验证的方案。
- 不能盲目迷信的原因:应用到简单问题上会让模式本身变成复杂度(黄金锤);许多模式会随着语言发展而消失;模式成为目的后,设计就会本末倒置。
- 实战原则:从问题出发,以简单代码开始,产生压力时再重构为模式。用于阅读时则可以大胆使用。

