设计模式入门:从历史到实战选择
说实话,每次带新人时,总有人问我:「设计模式到底是个啥?学了有用吗?」
我的回答很简单:设计模式就是前辈们踩过的坑,总结出来的最佳实践。 你想想看,软件开发这么多年,很多问题其实是重复出现的。与其每次都重新发明轮子,不如直接拿来用。
一、设计模式的历史:从建筑到软件
设计模式这个概念,最早不是计算机领域的。它来自建筑学。
1977年,建筑师克里斯托弗·亚历山大写了一本书叫《建筑模式语言》。他提出:好的建筑都有一些共通的模式,比如「窗户要朝南」、「门的位置要合理」。这些模式可以复用。
到了1990年代,四位软件工程师——Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides——把这套思想搬到了软件开发中。他们合著了那本大名鼎鼎的《设计模式:可复用面向对象软件的基础》。
这四个人,江湖人称「GoF」(Gang of Four,四人帮)。
核心观点:设计模式不是凭空发明的,而是从大量优秀项目中提炼出来的「套路」。我当年刚入行时,总觉得设计模式是理论派的东西。直到有一次重构一个遗留系统,发现代码里到处都是if-else,改一个功能要动十几个文件。后来用策略模式一重构,整个世界清净了。
二、GoF 23种设计模式分类
GoF把23种模式分成了三大类。我习惯用一句话记住它们:「创建对象、组合结构、协调行为」。
| 分类 | 核心思想 | 包含模式 |
|---|---|---|
| 创建型模式 | 帮你把「对象怎么创建」这件事封装起来 | 单例、工厂方法、抽象工厂、建造者、原型 |
| 结构型模式 | 解决类和对象如何组合成更大的结构 | 适配器、桥接、组合、装饰、外观、享元、代理 |
| 行为型模式 | 关注对象之间的职责分配和通信 | 模板方法、策略、观察者、迭代器、责任链、命令、备忘录、状态、访问者、中介者、解释器 |
嗯,这里要注意:分类不是绝对的。 有些模式其实可以跨类别理解。比如「策略模式」本质上是行为型的,但如果你把它和工厂模式结合,也能用来创建对象。
三、为什么学习设计模式?
我遇到过不少开发者,觉得设计模式就是「花架子」。说实话,我以前也这么想。
直到有一次,我接手一个电商项目。订单状态处理那段代码,写了整整2000行if-else。每次加一个新状态,都要改好几个地方。测试同事都快疯了。
后来我用状态模式重构了那段代码。核心逻辑从2000行降到了300行。新增一个状态,只需要加一个类,改一行配置。
所以,学习设计模式的好处,我总结为三点:
- 沟通效率高: 你说「这里用观察者模式」,大家秒懂。不用解释半天「A对象要监听B对象的变化,然后...」
- 代码质量好: 设计模式天然支持开闭原则、依赖倒置等SOLID原则。代码更容易扩展和维护。
- 重构有方向: 烂代码怎么改?设计模式就是你的「目标状态」。我习惯先识别代码里的「坏味道」,然后匹配对应的模式去重构。
我的建议: 不要为了用模式而用模式。设计模式是工具,不是目的。如果一个简单的if-else就能解决问题,别硬套工厂模式。
四、如何选择设计模式?
这是最实际的问题。很多初学者面对23种模式,一脸懵:「我该用哪个?」
我个人习惯用「问题驱动法」。说白了,就是先看你要解决什么问题,再去找对应的模式。
下面这张图是我自己总结的选择思路:
举个例子。假设你正在开发一个支付系统,支持微信、支付宝、银行卡等多种方式。每次新增支付方式,都要改一大段if-else。这时候你问自己:「我遇到的问题是什么?」 答案是:行为需要动态切换。那就去行为型模式里找——策略模式,完美匹配。
避坑指南: 我曾经在一个小工具里用了抽象工厂模式,结果代码量翻了三倍,可维护性反而下降了。后来反思:那个工具只有两种产品,用简单工厂就够了。设计模式的选择要「量体裁衣」,别贪多求全。
五、学习设计模式的正确姿势
我见过太多人把23种模式的UML图背得滚瓜烂熟,一到写代码就懵了。
为什么?因为设计模式是「练」出来的,不是「背」出来的。
我的学习路径是这样的:
- 先理解问题: 每个模式解决的是什么痛点?没有这个模式,代码会烂成什么样?
- 再动手实现: 用Java和C++各写一遍。两种语言的特性不同,实现方式也有差异。
- 最后找场景: 在自己的项目里,看看有没有类似的「坏味道」。有的话,试着用模式重构。
一个小技巧: 我习惯在代码里加注释,标注「这里用了XX模式」。这样几个月后回头看,还能想起当初的设计意图。团队协作时,别人也能快速理解。
好了,关于设计模式的入门就聊到这儿。记住一句话:设计模式是地图,不是导航。 它告诉你有哪些路可以走,但最终选哪条,还得看你的具体场景。
公众号:蓝海资料掘金营,微信deep3321