很多人学设计模式学着学着就会进入一种很熟悉的状态名字都听过定义也背过甚至类图都看过但一写代码还是不知道什么时候该用这事其实特别正常。因为很多人从一开始就学反了。设计模式最不该先背的就是定义。你真正该先抓住的是它背后的问题意识。说白了设计模式压根不是什么“高级黑话大全”它本质上只是在回答 3 类问题对象该怎么创建才不乱类和对象该怎么组织才不僵一堆对象之间该怎么配合才不炸你只要把这 3 个问题想明白23 种设计模式就会一下子从“背诵题”变成“工具箱”。这篇文章我不按教科书那种路子讲。不甩一堆抽象定义不上来就给你灌术语。咱们就按最接地气的方式聊清楚一件事23 种设计模式看起来很多其实背后就那几个思路。如果你正在学 C、学面向对象、学架构设计这篇文章你可以直接收藏。因为它不是让你死记而是帮你把整套设计模式真正“串起来”。一、先记这个总框架23 种模式本质上就分 3 大类GoF 经典设计模式一共 23 种但真没必要一上来就一个一个背。你先记住下面这句话设计模式 创建型 结构型 行为型这 3 大类几乎已经把思路讲完了。1. 创建型模式它关心的核心问题是对象怎么创建才更合理因为很多时候问题根本不在于“能不能 new”而在于谁来创建创建哪一种是不是只能创建一个创建过程是不是太复杂能不能别每次都从头造创建型模式解决的是“对象出生这件事”。2. 结构型模式它关心的核心问题是类和对象之间关系怎么搭才更顺程序一复杂最容易乱掉的就是结构。接口对不上怎么办继承一多就爆炸怎么办一堆对象要拼成树怎么办子系统太复杂调用太麻烦怎么办结构型模式解决的是“代码骨架怎么搭”。3. 行为型模式它关心的核心问题是对象之间到底怎么协作才不会互相拖垮系统复杂以后真正难的通常不是类不够而是对象之间关系太乱。请求该交给谁一个对象变了别人怎么知道一段逻辑里算法怎么切一个对象状态变了行为怎么跟着变行为型模式解决的是“对象之间怎么配合”。如果你把写程序理解成组一个团队创建型模式是在解决“人怎么招进来”结构型模式是在解决“组织结构怎么搭”行为型模式是在解决“团队怎么协作”只要这个总图进脑子里了后面 23 种模式就不再是散点了。二、创建型模式别只会new对象怎么出生本身就是设计很多初学者有个误区觉得对象创建这件事特别自然new就完了。但项目一大你就会发现真正容易把系统写僵的恰恰就是“对象怎么造”。下面这 5 种模式都是在解决“对象出生方式”。1. 单例模式有些对象全局就该只有一个单例模式特别好理解一个类全局只保留一个实例。它适合什么场景比如日志器、配置中心、连接池管理器、线程池管理器。这些东西你如果到处 new最后状态一定乱。你可以把它理解成公司前台。全公司通常只需要一个前台不会每层楼自己搞一套接待系统。一句话记住它单例模式解决的是“这个对象是不是只能有一个”。2. 工厂方法模式别在业务里到处硬写具体类工厂方法模式解决的是另一种常见问题对象别在业务逻辑里直接写死创建。比如你要创建文档对象有WordDocument、PdfDocument、MarkdownDocument。如果你在业务里到处new以后每加一种文档类型原逻辑都要改。工厂方法的意思就是“创建哪一种对象”不要散落在业务里而是交给工厂处理。一句话记住它工厂方法模式解决的是“对象创建逻辑别写死”。3. 抽象工厂模式不是造一个是造一整套如果工厂方法是“造一个产品”那抽象工厂就是一次造一整套互相配套的产品。比如 Windows 风格按钮要配 Windows 风格输入框Mac 风格按钮也要配 Mac 风格输入框。你肯定不想把页面拼成“按钮是 Windows 风输入框是 Mac 风”那看起来就像半路拼出来的。一句话记住它抽象工厂模式解决的是“同一产品族怎么整套生产”。4. 建造者模式对象太复杂就分步骤慢慢搭建造者模式特别适合这种场景对象很复杂不适合一个构造函数一把梭。比如造房子有地基、墙体、屋顶、窗户、装修。你完全可以一步一步建而不是把十几个参数一口气全塞进构造函数。一句话记住它建造者模式解决的是“复杂对象怎么分步骤创建”。5. 原型模式别每次都从头造直接复制一个现成的原型模式的思路很像你做 PPT。不是每一页都从空白页重新搭而是先复制一个模板再改内容。这就是原型模式的味道不从零造对象直接基于已有对象克隆。一句话记住它原型模式解决的是“相似对象怎么快速复制”。创建型模式真正想提醒你的是什么就一句话创建对象从来不是小事。很多系统后面为什么一改就乱不是因为业务逻辑本身多复杂而是因为最开始对象创建方式就写死了。三、结构型模式代码能跑不算赢关系顺不顺才是关键写项目写到后面最让人头疼的往往不是“功能做不出来”而是这个模块和那个模块怎么接这个类和那个类怎么关联想扩展一下为什么一改就牵一串这时候你就会发现结构型模式真的特别值钱。6. 适配器模式接口对不上就加个翻译层适配器模式的味道非常像插头转换器。老设备很好不想扔新插座也不能改那就加一个中间转换层。在代码里也是一样老系统接口和新系统接口不一致但老代码又值得复用那就用适配器把它“翻译”一下。一句话记住它适配器模式解决的是“接口不兼容”。7. 桥接模式两个维度都在变别硬靠继承顶桥接模式最适合处理这种情况有两条独立变化的线。比如图形类型在变绘制方式也在变如果你用继承把它们硬绑在一起类数量很快就爆炸。桥接模式的思路就是把它们拆开各变各的再通过组合连起来。一句话记住它桥接模式解决的是“两个维度同时变化时类爆炸”。8. 组合模式树形结构里单个和整体最好统一处理组合模式非常适合树状结构。比如组织架构文件夹结构菜单系统一个员工是节点一个部门也是节点部门下面还能挂部门还能挂员工。组合模式的核心就是单个对象和对象组合尽量用统一方式对待。一句话记住它组合模式解决的是“树形结构统一处理”。9. 装饰器模式不改原对象也能一层层加功能装饰器模式是非常实战的一种模式。比如一杯咖啡加牛奶加糖加巧克力如果全靠继承你会得到一棵越来越离谱的类树。但如果用装饰器你就是一层一层往外包。一句话记住它装饰器模式解决的是“功能动态叠加”。10. 外观模式底层再复杂对外也要好用外观模式特别像“总控面板”。比如你想“看电影”但底层可能要开投影切输入源开音响调音量开播放器如果每次都自己调一遍调用方会烦死。外观模式就是把这一串动作封成一个简单入口。一句话记住它外观模式解决的是“复杂子系统怎么简化调用”。11. 享元模式能共享的别重复造一千遍享元模式有点像“极致省资源”。它的核心思路是能共享的状态就共享。比如文字编辑器里的字符对象字符本身也许可以复用而字体、大小、颜色这些展示信息可以外部传入。一句话记住它享元模式解决的是“大量相似小对象怎么复用”。12. 代理模式不直接碰真实对象先过我这一关代理模式就是在真实对象前面加一个中间层。这个中间层可以做很多事延迟加载权限控制缓存远程调用日志记录比如图片第一次展示时再加载这是虚拟代理比如只有管理员能看余额这是保护代理。一句话记住它代理模式解决的是“访问过程需要被控制”。结构型模式真正想提醒你的是什么还是一句话代码结构一旦搭歪后面所有优化都会变辛苦。很多项目不是功能做不出来而是结构太别扭导致一改就连锁反应。四、行为型模式真正难的不是写类而是让类别互相拖后腿项目一开始类少的时候大家都挺和谐。但一旦类多了对象多了逻辑复杂了真正的麻烦才开始谁通知谁谁调用谁谁做决定状态变了怎么办行为型模式解决的就是这类“协作混乱”。13. 责任链模式别一上来就指定处理人让请求往后传责任链模式就像逐级审批。报销单先给部门经理不够权限再给财务再不够再给总经理。调用方不需要知道最终谁处理只负责把请求丢到链条起点。一句话记住它责任链模式解决的是“请求到底谁来接”。14. 命令模式把操作本身封装成对象命令模式的厉害之处在于动作不只是动作它也可以变成对象。这样你就能做很多事记录历史撤销操作重做操作排队执行比如遥控器控制灯和风扇按钮不直接碰设备而是发送命令。一句话记住它命令模式解决的是“操作怎么对象化”。15. 解释器模式规则和表达式也能拆成对象来算解释器模式适合简单规则系统。比如算术表达式条件规则小型 DSL它的核心就是把语法规则表示成对象结构再逐层解释。一句话记住它解释器模式解决的是“简单规则怎么解释执行”。16. 迭代器模式怎么遍历不该暴露集合内部细节迭代器模式其实特别常见。它解决的是集合内部怎么存无所谓但遍历方式要统一。你只需要一个个取元素不需要知道底层到底是数组、链表还是别的结构。一句话记住它迭代器模式解决的是“遍历逻辑和集合结构解耦”。17. 中介者模式对象别两两乱连统一找协调者中介者模式就是把“网状关系”改成“星型关系”。最经典的例子就是聊天室。用户不直接给所有人发消息而是先把消息丢给聊天室聊天室再统一分发。一句话记住它中介者模式解决的是“多对象关系太乱”。18. 备忘录模式先把状态存起来后面才能撤销备忘录模式特别适合做撤销和回滚。比如文本编辑器撤销游戏存档配置回滚它的关键不只是“存”而是在不破坏封装的前提下把状态安全保留。一句话记住它备忘录模式解决的是“状态怎么保存和恢复”。19. 观察者模式一个对象变了一批对象跟着收到通知观察者模式的本质很像订阅机制。一个对象状态变了所有订阅它的人都会被通知。比如天气站一更新天气所有订阅天气的客户端都自动收到消息。一句话记住它观察者模式解决的是“一个变多个跟着变”。20. 状态模式状态一变行为也得跟着变状态模式非常适合这类对象在不同状态下同一个动作会有完全不同的表现。比如自动售货机没投币已投币已选商品同样是“点击按钮”不同状态下逻辑完全不一样。一句话记住它状态模式解决的是“状态不同行为不同”。21. 策略模式流程不变但算法可以随时换策略模式是最容易落地的一种模式。它的场景通常是同一个问题有多种算法。比如价格计算原价满减折扣流程不变只是中间的计算方式变了。一句话记住它策略模式解决的是“同一问题有多种算法可切换”。22. 模板方法模式流程先定死细节再交给子类模板方法模式特别适合这种情况整体流程很稳定但中间某几步可以变化。比如泡茶和泡咖啡烧水冲泡倒杯加配料大流程差不多但细节步骤不一样。一句话记住它模板方法模式解决的是“流程不变细节可变”。23. 访问者模式结构别老改操作可以继续加访问者模式经常出现在这种场景对象结构相对稳定但你总想新增操作。比如员工对象已经很稳定了但你后面还要不断加薪资统计绩效分析报表导出审计检查如果这些全塞回员工类里会越来越臃肿。访问者模式就是把这些操作外提出来。一句话记住它访问者模式解决的是“结构稳定但操作不断增加”。行为型模式真正想提醒你的是什么一句话就够真正让系统崩起来的往往不是类不够而是对象之间关系太乱。五、别再一个个背名字了记“问题”比记“定义”有用太多如果你看完前面还是觉得 23 种很多那就记下面这张“问题清单”。以后你写代码只要先想到问题再去反推模式效率会高很多。遇到这些问题优先想到这些模式只能有一个对象单例创建逻辑不想写死工厂方法想成套创建对象抽象工厂创建过程太复杂建造者想复制现成对象原型接口不兼容适配器两个维度都在变桥接树形结构统一处理组合动态叠加功能装饰器想简化复杂系统外观大量小对象要复用享元访问需要受控代理请求逐级传递责任链操作需要记录和撤销命令规则表达式要解释解释器要遍历但不暴露内部结构迭代器多对象协调沟通中介者状态需要保存和恢复备忘录一个变多个通知观察者状态变了行为也变状态算法需要切换策略流程固定但细节可变模板方法结构稳定但操作增加访问者看到这里其实你已经能发现一件事了设计模式并不是 23 个孤零零的名字而是 23 种“常见代码问题”的经典处理方式。六、很多人学不会设计模式不是因为难而是因为学法不对这里我直接说 3 个最常见的坑。坑 1只背定义不看场景这是最多人中的坑。你把定义背得再顺如果不知道它解决什么麻烦到代码里还是不会用。真正有效的学法是先看它在解决什么问题再看它长什么结构。坑 2见模式就想套设计模式不是越多越高级。很多代码最大的问题不是“没用模式”而是“问题根本没复杂到那个程度却硬套了模式”。一句话模式是为了解决问题不是为了显得高级。坑 3不做模式对比很多模式单看能懂放一起就容易混。比如适配器和桥接都像“中间加一层”代理和装饰器都像“包一层对象”状态和策略结构也很像所以后面学习的时候一定要多做对比。只学单个不看边界最后很容易“似懂非懂”。七、如果你真想学会建议按这个顺序来别一口气从第 1 个模式读到第 23 个。更顺的方式是分阶段第一阶段先建立直觉优先看这几个单例模式工厂方法模式策略模式观察者模式这几个最容易建立感觉也最常见。第二阶段再理解结构接着看适配器模式桥接模式组合模式装饰器模式外观模式代理模式这一阶段重点不是背定义而是体会“为什么要这么搭关系”。第三阶段最后理解协作最后看责任链模式命令模式中介者模式状态模式模板方法模式访问者模式这时候你会更容易把设计模式理解成“协作方案”而不是“类图题”。八、完整资料我已经整理好了能看、能跑、能下载、能分享为了方便系统学习我已经把这套 C 设计模式内容整理成了一整套专栏资料包含23 种设计模式示例代码每种模式的独立讲解文档统一的CMake构建结构专栏首页、总览页、文章页适合继续补充和长期维护的整理方式你可以把它当成C 设计模式学习资料面试复习资料技术分享底稿博客专栏素材团队培训基础材料下载入口我用夸克网盘给你分享了「C设计模式代码讲解.7z」点击链接或复制整段内容打开「夸克网盘APP」即可获取。 /~5a023YUCBd~:/ 链接https://pan.quark.cn/s/11103051338d如果你身边刚好有人在学C面向对象设计设计模式架构思维你可以直接把这篇文章和整套资料转给他。你甚至可以直接配这一句这是一套按 C 场景整理的 23 种设计模式资料包含代码、讲解、专栏总览和文章版说明比较适合系统入门、复习和分享。如果你自己就在做技术公众号、博客或者知识库整理这套东西也可以直接拿来继续扩展成系列内容。