设计模式总结与面试技巧:如何回答设计模式问题,项目中的模式应用经验分享
走到这里,咱们已经把 23 种经典设计模式都过了一遍。说实话,能坚持看到第 50 章,你已经是同龄人中的佼佼者了。但面试官真正想听的,不是你背下了多少种模式的 UML 图,而是——你什么时候该用,什么时候不该用,以及你踩过哪些坑。
这一章,我就以一个面试官的身份,跟你聊聊怎么回答设计模式相关的问题。顺便分享一些我在项目中真实用过的模式组合,希望能帮你把「纸上谈兵」变成「实战经验」。
面试官到底想考察什么?
很多候选人一上来就背定义:「单例模式确保一个类只有一个实例…」嗯,这没错,但太浅了。面试官真正想看的,是这三层能力:
| 层次 | 考察点 | 典型问题 |
|---|---|---|
| 第一层 | 模式的基本概念与分类 | 请说出工厂模式和抽象工厂模式的区别 |
| 第二层 | 模式的应用场景与取舍 | 什么情况下你会用策略模式而不是状态模式? |
| 第三层 | 模式在真实项目中的落地 | 你在项目中如何组合使用观察者模式和中介者模式? |
我个人习惯,问完第一层后,会立刻追问第二层和第三层。如果你只能答出第一层,那分数大概只有 60 分。
回答设计模式问题的「三段式」结构
我建议你采用这个结构来回答,既清晰又有深度:
- 一句话说清本质:这个模式解决了什么问题?
- 结合场景讲用法:我在哪个项目中用过?为什么选它?
- 点出坑与权衡:这个模式有什么副作用?什么情况下不该用?
举个例子,面试官问「你用过观察者模式吗?」
❌ 低分回答:「用过,就是发布-订阅,一个对象变化通知所有观察者。」
✅ 高分回答:
「观察者模式本质上是解耦通知方和接收方。我在做即时通讯模块时用过它——用户上线、下线、消息到达,都需要通知 UI 层更新。当时我选了观察者模式而不是直接回调,因为观察者可以动态增删,而且支持一对多。但后来也踩了个坑:观察者太多时,通知顺序不可控,而且如果观察者回调里做了耗时操作,会阻塞通知线程。所以后来我加了一个异步队列,把通知丢到线程池里去执行。」
你看,这样回答,面试官会眼前一亮。
项目中常见的模式组合
真实项目里,很少只用一种模式。我分享几个我实际用过的组合拳:
组合一:策略模式 + 工厂模式
这是最经典的组合。我在做支付网关时,有微信支付、支付宝、银联等多种渠道。每个渠道的支付逻辑不同,但对外接口一致。
- 策略模式:定义支付策略接口,每种渠道实现自己的算法
- 工厂模式:根据传入的渠道类型,创建对应的策略对象
这样做的好处是:新增一个支付渠道,只需要加一个策略类,不改任何业务代码。我曾经见过同事把支付逻辑写在一大坨 if-else 里,后来加一个渠道改了 5 个文件…嗯,那滋味不好受。
组合二:观察者模式 + 中介者模式
UI 开发中经常遇到。比如一个对话框里有多个控件:输入框、下拉框、按钮。它们之间互相影响。
- 如果直接用观察者模式,每个控件都要观察其他控件,形成网状依赖
- 引入中介者模式后,所有控件只跟中介者通信,中介者负责协调
说白了,观察者模式解决「一对多」的通知问题,中介者模式解决「多对多」的耦合问题。两者结合,代码会清爽很多。
组合三:模板方法模式 + 工厂模式
做数据处理框架时常用。比如数据导入流程:读取文件 → 校验格式 → 转换数据 → 写入数据库。整体流程固定,但每一步的具体实现可能不同。
- 模板方法模式:定义流程骨架,子类重写某些步骤
- 工厂模式:根据文件类型(CSV、Excel、JSON)创建对应的处理子类
我曾经用这个组合写过一套 ETL 工具,后来团队其他人想加新的文件格式,只需要继承模板类,实现三个方法就行。那感觉,挺爽的。
避坑指南:设计模式不是万能药
说到坑,我得多说几句。很多新手容易犯的毛病是「为了用模式而用模式」。我曾经见过一个项目,代码里用了 10 多种设计模式,但业务逻辑只有 2000 行。结果呢?新来的同事看代码看了三天,愣是没看懂一个简单的订单流程。
我总结了几条经验:
- 不要过早引入模式:先写简单的代码,等发现变化点再重构。我习惯用「三次原则」——同一个变化出现三次,才考虑用模式。
- 模式之间可以混用,但要克制:一个类里同时用工厂、策略、装饰器、代理…那这个类基本废了。
- 优先用语言特性:C++ 的 lambda、std::function、模板元编程,有时候比设计模式更简洁。比如策略模式完全可以用 std::function 替代。
面试中如何展示你的模式经验?
面试官问你「你在项目中用过哪些设计模式」时,不要只列名字。我建议你准备 2-3 个真实案例,每个案例按这个结构讲:
- 背景:什么项目?什么模块?遇到了什么问题?
- 选型:为什么选这个模式?有没有考虑过其他方案?
- 实现:简单描述代码结构,可以画个类图
- 效果:解决了什么问题?带来了什么好处?
- 反思:如果重来一次,你会怎么改进?
举个例子,我面试时经常这样讲:
「我之前做一个配置管理系统,需要支持多种配置来源:本地文件、远程 HTTP、数据库。一开始我用 if-else 判断来源,后来发现每加一种来源就要改主逻辑,违反了开闭原则。于是我引入了策略模式,每种来源一个策略类,再配合工厂模式根据配置类型创建策略。改完之后,新增来源只需要加一个类,主逻辑完全不用动。不过后来我发现,如果策略类太多,工厂类会变得臃肿。所以我又引入了注册表模式,让策略类自己注册到工厂里。嗯,如果重来一次,我可能会直接用 std::map 加 lambda 来简化工厂。」
你看,这样讲既有深度,又有反思,面试官会觉得你是个有经验的工程师。
知识体系总览
最后,我用一张图来总结整个设计模式的知识体系。这张图我面试时经常画在白板上,帮你理清思路:
写在最后
设计模式不是背出来的,是用出来的。我见过太多人把《设计模式》翻烂了,面试时却答不出一个像样的项目案例。反过来,那些真正在项目中踩过坑、重构过代码的工程师,哪怕记不全 23 种模式的名字,也能轻松通过面试。
所以,我的建议是:别急着背,先动手写。找一个你之前写过的模块,试着用设计模式重构一下。感受一下代码从「能跑」变成「好改」的过程。那种感觉,比背 100 遍定义都管用。
好了,关于设计模式的面试技巧,我就分享到这里。希望你在面试中能游刃有余,把「我会用」变成「我懂为什么用」。加油。
公众号:蓝海资料掘金营,微信 deep3321