一、设计模式概述
设计模式这个话题,我讲了十几年了。每次开课我都会问学员一个问题:你写代码的时候,有没有遇到过“这代码我好像在哪写过”的感觉?
如果有,那你其实已经摸到设计模式的门槛了。
说白了,设计模式就是前辈们总结出来的、解决特定问题的“套路”。就像下棋有定式,做菜有菜谱,写代码也有它的经典解法。我个人习惯把设计模式理解为:在特定场景下,经过验证的、可复用的解决方案。
1.1 什么是设计模式
设计模式这个概念,最早来自建筑领域。Christopher Alexander 说过:“每个模式描述了一个在我们环境中反复出现的问题,然后描述了该问题的核心解决方案。”
放到软件工程里,意思是一样的:
- 问题:你在开发中反复遇到的场景
- 上下文:这个问题出现的环境约束
- 解决方案:经过验证的、通用的设计结构
核心要点:设计模式不是代码库,不是框架,不是可以直接 copy 的代码片段。它是一种思想,一种沟通语言。
举个例子。你想想看,当我说“这里用个观察者模式”,有经验的同事立刻就知道:哦,你要做事件通知,一对多的依赖关系。不需要我再画半天图解释。这就是设计模式的价值——提升团队沟通效率。
我在项目中遇到过最典型的案例:一个电商系统的订单状态变更。一开始大家各自写各自的,有的用回调,有的用事件总线,有的直接硬编码调用。后来统一用观察者模式重构,代码量减少了40%,新人也容易上手。
1.2 设计模式的分类
GoF(Gang of Four,四人帮)把23种经典设计模式分成了三类。这个分类法我用了快20年,依然觉得非常合理。
| 类别 | 核心关注点 | 典型模式 | 一句话理解 |
|---|---|---|---|
| 创建型 | 对象的创建机制 | 单例、工厂、建造者 | 把“new”这件事封装起来 |
| 结构型 | 对象/类的组合方式 | 适配器、代理、装饰器 | 把零散的类拼成灵活的结构 |
| 行为型 | 对象间的交互与职责分配 | 策略、观察者、模板方法 | 让对象之间“好好说话” |
创建型模式
创建型模式解决的是“怎么把对象造出来”的问题。你可能会说:“new 一下不就行了?”嗯,在简单场景下确实可以。但当你面对复杂对象、需要控制实例数量、或者想隐藏创建细节时,直接 new 就会出问题。
我曾经接手过一个项目,里面到处都是 new XXX(),结果要换一个数据库连接池实现,改了十几个文件。如果用工厂模式,改一处就够了。
结构型模式
结构型模式关注的是“怎么把类和对象组合成更大的结构”。说白了,就是搭积木。好的结构型设计,能让你的系统像乐高一样灵活——想加一块就加一块,想换一块就换一块。
我记得有一次做支付系统对接,需要支持微信、支付宝、银联三种渠道。如果用 if-else 硬写,那代码简直没法看。后来用适配器模式,每个渠道写一个适配器,核心逻辑完全不用改。
行为型模式
行为型模式解决的是“对象之间怎么协作”。这是最考验设计功底的一类模式。因为对象多了,交互就复杂了。怎么分配职责?怎么传递消息?怎么避免耦合?
我建议初学者先从策略模式和观察者模式入手。这两个在实际项目中用得最多,也最容易理解。
1.3 设计模式与架构原则的关系
很多人学设计模式,学了半天还是不知道怎么用。为什么?因为只记住了模式的结构,没理解背后的原则。
设计模式不是凭空冒出来的。它们都是基于一些更底层的架构原则推导出来的。我列几个最核心的原则:
- 开闭原则(OCP):对扩展开放,对修改关闭。说白了,加功能的时候尽量别改老代码。
- 单一职责(SRP):一个类只做一件事。这个说起来简单,做起来难。
- 依赖倒置(DIP):依赖抽象,不要依赖具体实现。
- 接口隔离(ISP):接口要小而专,不要大而全。
- 里氏替换(LSP):子类必须能替换父类。
我的经验:当你拿不准该用哪个模式时,先回头看看这些原则。很多时候,原则会告诉你答案。比如“这个类要不要拆?”——单一职责原则说了算。
举个例子。策略模式本质上就是开闭原则的体现:你加一种新策略,不需要改原有策略的代码。观察者模式则是依赖倒置的体现:观察者和被观察者都依赖于抽象接口,而不是彼此。
避坑指南:我曾经见过有人为了用设计模式而用设计模式。一个只有三个类的系统,硬塞了五个模式进去。结果代码变得极其复杂,维护成本翻了好几倍。记住:模式是工具,不是目的。不要为了用模式而用模式。
最后,我用一张图来总结本章的核心知识体系:
这张图想表达的核心思想是:设计模式不是孤立的。上面是三大分类,下面是架构原则。模式是原则的具体实现,原则是模式的指导思想。两者缺一不可。
好了,这一章就到这里。记住一句话:设计模式是经验的结晶,不是教条的束缚。带着问题去学,带着场景去用,你才能真正掌握它。
公众号:蓝海资料掘金营,微信deep3321