一、设计模式概述
设计模式这个话题,说实话我讲了十几年了。每次带新人或者做技术分享,我总会从这个问题开始——「你写代码的时候,有没有遇到过那种「这问题我好像在哪见过」的感觉?」
设计模式,说白了就是前辈们把这种「似曾相识」的问题,总结成了一套标准解法。它不是让你背公式,而是让你在面对复杂问题时,脑子里能快速浮现出几种靠谱的解决思路。
1.1 设计模式的定义
先给个官方点的说法:设计模式是在特定上下文中,针对常见问题的可复用解决方案。
嗯,这句话有点绕。我换个说法——设计模式就是一套「套路」。就像下棋有开局定式,写代码也有自己的定式。你不需要每次都从零开始想怎么解耦、怎么扩展,直接用现成的模式,又快又稳。
核心要点:设计模式不是代码库,不是框架,而是一种「思想模板」。它告诉你「遇到这类问题,可以这样组织你的类和对象」。
我在项目中遇到过不少同事,把设计模式当成了「银弹」。觉得用了设计模式代码就高级了。其实不然。模式用错了,反而会让代码变得臃肿。记住一句话:模式是工具,不是目的。
1.2 设计模式的起源——GoF四人组
说到设计模式,就绕不开四个人:Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides。江湖人称「GoF四人组」(Gang of Four)。
1994年,他们出了一本书,叫《Design Patterns: Elements of Reusable Object-Oriented Software》。这本书有多牛?它直接定义了设计模式这个领域。直到今天,我们聊的23种经典设计模式,基本都来自这本书。
我记得刚入行那会儿,啃这本书啃得头皮发麻。不是因为难,而是因为——你发现你之前写的很多代码,原来都是在「重新发明轮子」。那种感觉,既羞愧又兴奋。
| 作者 | 贡献 |
|---|---|
| Erich Gamma | Eclipse JDT核心开发者,JUnit联合创始人 |
| Richard Helm | 面向对象设计专家,模式理论推动者 |
| Ralph Johnson | UI框架设计专家,Smalltalk社区领袖 |
| John Vlissides | 模式语言与复用技术研究者 |
个人建议:如果你刚开始学设计模式,别急着把23种全背下来。先掌握最常用的5-6种(单例、工厂、观察者、策略、适配器、装饰器),剩下的遇到问题再查。我当年就是一口气啃完,结果消化不良。
1.3 设计模式的分类
GoF把23种模式分成了三大类:创建型、结构型、行为型。这个分类很讲究,你想想看——
- 创建型:管的是「对象怎么生出来」
- 结构型:管的是「类和对象怎么组合」
- 行为型:管的是「对象之间怎么交互」
说白了,就是从对象的出生、结构、行为三个维度去解决问题。
创建型模式(5种)
- 单例模式:全局只有一个实例。我经常在配置管理、日志模块里用。
- 工厂方法:让子类决定实例化哪个类。适合产品族扩展的场景。
- 抽象工厂:创建一组相关对象。跨平台UI组件库的标配。
- 建造者模式:分步骤构建复杂对象。比如组装一台电脑,一步步来。
- 原型模式:通过克隆创建对象。适合创建成本高的对象。
结构型模式(7种)
- 适配器模式:让不兼容的接口能一起工作。我经常用它来对接第三方SDK。
- 桥接模式:将抽象与实现分离。比如画不同形状、不同颜色的图形。
- 组合模式:树形结构,部分-整体一致。文件系统就是典型。
- 装饰器模式:动态给对象添加功能。Java I/O流就是活例子。
- 外观模式:提供统一的高层接口。封装复杂子系统。
- 享元模式:共享细粒度对象。游戏里的子弹、粒子系统常用。
- 代理模式:控制对对象的访问。延迟加载、权限控制都靠它。
行为型模式(11种)
- 模板方法:定义算法骨架,子类实现细节。
- 策略模式:算法族可互换。支付方式切换就是典型。
- 观察者模式:一对多依赖,状态变化通知所有观察者。
- 迭代器模式:统一遍历集合的方式。
- 责任链模式:请求沿链传递,直到有人处理。
- 命令模式:将请求封装为对象。支持撤销、重做。
- 备忘录模式:保存和恢复对象状态。
- 状态模式:对象行为随状态改变。
- 访问者模式:在不改变元素类的前提下增加新操作。
- 中介者模式:用中介对象协调多个对象交互。
- 解释器模式:定义语言文法并解释执行。
避坑指南:我曾经在一个项目中,为了「优雅」硬套了7个设计模式。结果代码变得极其难懂,新同事看了三天没看懂。后来我重构,只保留了2个真正需要的模式。记住:模式是为你服务的,不是让你为模式服务的。
1.4 设计模式与架构原则的关系
这个问题,我经常被问到:「设计模式和架构原则,到底先学哪个?」
我的回答是:先学原则,再学模式。为什么?因为原则是「道」,模式是「术」。你懂了道,术才能用得对。
几个核心原则,我简单列一下:
- 单一职责原则(SRP):一个类只做一件事。这是最基础的原则,但也是最容易被打破的。
- 开闭原则(OCP):对扩展开放,对修改关闭。说白了就是——加功能不改老代码。
- 里氏替换原则(LSP):子类必须能替换父类。别搞出「正方形继承长方形」那种反逻辑的设计。
- 接口隔离原则(ISP):接口要小而专,别搞大而全的「上帝接口」。
- 依赖倒置原则(DIP):依赖抽象,不依赖具体实现。这是解耦的核心。
你想想看,设计模式其实就是这些原则的具体落地。比如策略模式,就是开闭原则的完美体现——你加一种新策略,不需要改原有代码,只需要新增一个策略类。再比如依赖倒置原则,几乎所有的模式都在用它。
一句话总结:原则是「为什么这么做」,模式是「具体怎么做」。两者相辅相成,缺一不可。
下面这张图,是我自己整理的设计模式知识体系。每次给团队做培训,我都会先展示这张图。它能帮你快速建立全局认知——
这张图你看懂了吗?从上往下看:设计模式分为三大类,每一类下面有若干具体模式。而最底部,是支撑所有模式的五大架构原则。没有这些原则,模式就是空中楼阁。
学习路径建议:我个人习惯是「先原则,再模式,最后反哺原则」。什么意思呢?就是先理解五大原则,然后学模式的时候,不断问自己「这个模式体现了哪个原则?」。等你模式用熟了,再回头看原则,会有更深的理解。这是一个螺旋上升的过程。
好了,这一章就到这里。设计模式的世界很大,但别怕。从今天开始,你每学一个模式,都可以问自己三个问题:
- 这个模式解决了什么问题?
- 它体现了哪些架构原则?
- 我手头的项目里,有没有类似的场景?
带着这三个问题去学,你会发现——设计模式不是死记硬背的,而是自然而然「长」出来的。
公众号:蓝海资料掘金营,微信deep3321