设计模式总结与面试技巧:如何回答设计模式问题,项目中的模式应用经验分享

走到这里,咱们已经把 23 种经典设计模式都过了一遍。说实话,能坚持看到第 50 章,你已经是同龄人中的佼佼者了。但面试官真正想听的,不是你背下了多少种模式的 UML 图,而是——你什么时候该用,什么时候不该用,以及你踩过哪些坑

这一章,我就以一个面试官的身份,跟你聊聊怎么回答设计模式相关的问题。顺便分享一些我在项目中真实用过的模式组合,希望能帮你把「纸上谈兵」变成「实战经验」。

面试官到底想考察什么?

很多候选人一上来就背定义:「单例模式确保一个类只有一个实例…」嗯,这没错,但太浅了。面试官真正想看的,是这三层能力:

层次 考察点 典型问题
第一层 模式的基本概念与分类 请说出工厂模式和抽象工厂模式的区别
第二层 模式的应用场景与取舍 什么情况下你会用策略模式而不是状态模式?
第三层 模式在真实项目中的落地 你在项目中如何组合使用观察者模式和中介者模式?

我个人习惯,问完第一层后,会立刻追问第二层和第三层。如果你只能答出第一层,那分数大概只有 60 分。

回答设计模式问题的「三段式」结构

我建议你采用这个结构来回答,既清晰又有深度:

  1. 一句话说清本质:这个模式解决了什么问题?
  2. 结合场景讲用法:我在哪个项目中用过?为什么选它?
  3. 点出坑与权衡:这个模式有什么副作用?什么情况下不该用?

举个例子,面试官问「你用过观察者模式吗?」

❌ 低分回答:「用过,就是发布-订阅,一个对象变化通知所有观察者。」

✅ 高分回答:

「观察者模式本质上是解耦通知方和接收方。我在做即时通讯模块时用过它——用户上线、下线、消息到达,都需要通知 UI 层更新。当时我选了观察者模式而不是直接回调,因为观察者可以动态增删,而且支持一对多。但后来也踩了个坑:观察者太多时,通知顺序不可控,而且如果观察者回调里做了耗时操作,会阻塞通知线程。所以后来我加了一个异步队列,把通知丢到线程池里去执行。」

你看,这样回答,面试官会眼前一亮。

项目中常见的模式组合

真实项目里,很少只用一种模式。我分享几个我实际用过的组合拳:

组合一:策略模式 + 工厂模式

这是最经典的组合。我在做支付网关时,有微信支付、支付宝、银联等多种渠道。每个渠道的支付逻辑不同,但对外接口一致。

  • 策略模式:定义支付策略接口,每种渠道实现自己的算法
  • 工厂模式:根据传入的渠道类型,创建对应的策略对象

这样做的好处是:新增一个支付渠道,只需要加一个策略类,不改任何业务代码。我曾经见过同事把支付逻辑写在一大坨 if-else 里,后来加一个渠道改了 5 个文件…嗯,那滋味不好受。

组合二:观察者模式 + 中介者模式

UI 开发中经常遇到。比如一个对话框里有多个控件:输入框、下拉框、按钮。它们之间互相影响。

  • 如果直接用观察者模式,每个控件都要观察其他控件,形成网状依赖
  • 引入中介者模式后,所有控件只跟中介者通信,中介者负责协调

说白了,观察者模式解决「一对多」的通知问题,中介者模式解决「多对多」的耦合问题。两者结合,代码会清爽很多。

组合三:模板方法模式 + 工厂模式

做数据处理框架时常用。比如数据导入流程:读取文件 → 校验格式 → 转换数据 → 写入数据库。整体流程固定,但每一步的具体实现可能不同。

  • 模板方法模式:定义流程骨架,子类重写某些步骤
  • 工厂模式:根据文件类型(CSV、Excel、JSON)创建对应的处理子类

我曾经用这个组合写过一套 ETL 工具,后来团队其他人想加新的文件格式,只需要继承模板类,实现三个方法就行。那感觉,挺爽的。

避坑指南:设计模式不是万能药

说到坑,我得多说几句。很多新手容易犯的毛病是「为了用模式而用模式」。我曾经见过一个项目,代码里用了 10 多种设计模式,但业务逻辑只有 2000 行。结果呢?新来的同事看代码看了三天,愣是没看懂一个简单的订单流程。

⚠️ 注意:设计模式的核心目的是「管理变化」,而不是「炫技」。如果一个模式引入的复杂度超过了它解决的问题,那就别用。

我总结了几条经验:

  • 不要过早引入模式:先写简单的代码,等发现变化点再重构。我习惯用「三次原则」——同一个变化出现三次,才考虑用模式。
  • 模式之间可以混用,但要克制:一个类里同时用工厂、策略、装饰器、代理…那这个类基本废了。
  • 优先用语言特性:C++ 的 lambda、std::function、模板元编程,有时候比设计模式更简洁。比如策略模式完全可以用 std::function 替代。

面试中如何展示你的模式经验?

面试官问你「你在项目中用过哪些设计模式」时,不要只列名字。我建议你准备 2-3 个真实案例,每个案例按这个结构讲:

  1. 背景:什么项目?什么模块?遇到了什么问题?
  2. 选型:为什么选这个模式?有没有考虑过其他方案?
  3. 实现:简单描述代码结构,可以画个类图
  4. 效果:解决了什么问题?带来了什么好处?
  5. 反思:如果重来一次,你会怎么改进?

举个例子,我面试时经常这样讲:

「我之前做一个配置管理系统,需要支持多种配置来源:本地文件、远程 HTTP、数据库。一开始我用 if-else 判断来源,后来发现每加一种来源就要改主逻辑,违反了开闭原则。于是我引入了策略模式,每种来源一个策略类,再配合工厂模式根据配置类型创建策略。改完之后,新增来源只需要加一个类,主逻辑完全不用动。不过后来我发现,如果策略类太多,工厂类会变得臃肿。所以我又引入了注册表模式,让策略类自己注册到工厂里。嗯,如果重来一次,我可能会直接用 std::map 加 lambda 来简化工厂。」

你看,这样讲既有深度,又有反思,面试官会觉得你是个有经验的工程师。

知识体系总览

最后,我用一张图来总结整个设计模式的知识体系。这张图我面试时经常画在白板上,帮你理清思路:

设计模式知识体系总览 创建型模式 结构型模式 行为型模式 单例 工厂方法 抽象工厂 建造者 原型 适配器 桥接 组合 装饰器 外观 代理 享元 策略 观察者 模板方法 命令 状态 职责链 中介者 迭代器 访问者 备忘录 解释器 共 23 种经典设计模式,分为三大类
💡 面试小技巧:面试官让你画类图时,不要纠结于完美的 UML 语法。用简单的方框和箭头,把核心关系说清楚就行。重点是「为什么这么设计」,而不是「箭头画得标不标准」。

写在最后

设计模式不是背出来的,是用出来的。我见过太多人把《设计模式》翻烂了,面试时却答不出一个像样的项目案例。反过来,那些真正在项目中踩过坑、重构过代码的工程师,哪怕记不全 23 种模式的名字,也能轻松通过面试。

所以,我的建议是:别急着背,先动手写。找一个你之前写过的模块,试着用设计模式重构一下。感受一下代码从「能跑」变成「好改」的过程。那种感觉,比背 100 遍定义都管用。

好了,关于设计模式的面试技巧,我就分享到这里。希望你在面试中能游刃有余,把「我会用」变成「我懂为什么用」。加油。


公众号:蓝海资料掘金营,微信 deep3321