真实面经题目 · 原创解析

常见设计模式有哪些,分别适合什么场景?

常见设计模式不适合只罗列名称,面试官更关注候选人是否理解模式背后的变化点、解耦方式和落地边界。高质量回答应按创建型、结构型、行为型展开,结合 Spring 和业务代码说明真实使用场景,同时明确模式不是越多越好,核心是让代码在扩展时少改动、在维护时更清晰。

出现于:阿里巴巴 · 后端开发

60 秒回答模板

常见设计模式可以按三类来理解:创建型主要解决对象怎么创建,例如单例用于全局唯一资源,工厂用于屏蔽对象创建细节,建造者用于构造复杂对象;结构型主要解决类或对象怎么组合,例如适配器用于兼容旧接口或第三方接口,装饰器用于在不改原类的情况下叠加能力,代理用于控制访问、延迟加载或增强调用;行为型主要解决对象之间如何协作,例如策略用于替换大量条件分支,模板方法用于固定流程、开放步骤扩展,观察者用于事件通知,责任链用于多处理器按顺序处理请求。项目中更应该从变化点出发选模式,比如支付渠道、优惠规则、风控校验适合策略或责任链,统一鉴权和日志适合代理或拦截器,第三方接口适配适合适配器。同时也要控制复杂度,简单场景不要为了套模式引入过多类。

考点 分类框架
主线 创建型场景
易错点 只罗列设计模式名称,不解释它们分别解决什么变化点和维护…

深入解析

01

分类框架

回答时可以先说明设计模式不是固定模板,而是对常见变化点的抽象。经典上可分为创建型、结构型、行为型三类:创建型关注对象创建过程,结构型关注对象组合和接口关系,行为型关注对象协作流程。这样开场能让答案从背诵清单变成有组织的工程判断,也方便后续把每个模式放到具体业务场景里解释。

02

创建型场景

创建型模式适合对象创建逻辑复杂、创建过程需要隔离或生命周期需要统一管理的场景。单例常用于配置中心客户端、线程池、连接池管理器等全局唯一对象,但要注意线程安全和测试隔离。工厂模式适合根据类型创建不同实现,例如不同支付渠道、不同消息发送器。建造者模式适合构造参数多、校验多、可选项多的对象,例如复杂查询条件、订单上下文或外部请求对象。

03

结构型场景

结构型模式适合在不大改既有代码的情况下调整对象关系。适配器用于接口不兼容但又必须复用旧系统或第三方 SDK 的场景,例如把外部支付回调转换成内部统一回调模型。装饰器用于动态增强功能,例如给数据读取能力叠加缓存、压缩、加密或限流。代理用于控制对目标对象的访问,常见于远程调用代理、事务代理、权限校验、延迟加载和监控埋点。

04

行为型场景

行为型模式更贴近业务流程和协作方式。策略模式适合一组算法或规则可替换的场景,例如价格计算、优惠计算、路由选择。模板方法适合流程稳定但部分步骤变化的场景,例如导入文件时固定校验、解析、落库流程,不同文件格式只重写解析步骤。观察者适合事件发布和订阅,例如订单支付成功后通知积分、库存、消息模块。责任链适合多个处理器按顺序拦截或校验请求,例如参数校验、风控、权限、幂等等。

05

Spring 例子

Spring 本身就是设计模式落地的典型例子。Bean 默认单例体现了单例思想,但由容器托管生命周期而不是手写全局变量;BeanFactory 和 FactoryBean 体现工厂思想;AOP 动态代理用于事务、缓存、权限和日志增强;ApplicationEvent 体现观察者思想;JdbcTemplate、RestTemplate 体现模板方法思想;HandlerInterceptor、Filter 链和部分安全框架体现责任链思想。用 Spring 例子能说明候选人见过框架中的工程化实现。

06

业务落地

在业务项目中,最常见的落地方式是围绕变化点抽象。比如多支付渠道可以用策略封装微信、银行卡、余额等实现,再用工厂或注册表按渠道选择策略;多级风控可以用责任链让每个校验器只负责一个规则;对接多个第三方物流接口可以用适配器统一入参和出参;订单状态变化后通知多个子系统可以用观察者或事件机制解耦同步流程。

07

选择边界

设计模式的价值是控制变化成本,不是增加类的数量。对于只有一个实现、短期没有扩展需求、逻辑非常简单的代码,直接写清楚往往比强行抽象更好。只有当条件分支频繁增长、第三方接口差异明显、流程复用明显、横切逻辑重复出现时,模式才会带来收益。回答时最好主动说明这种边界,体现对可维护性和复杂度的平衡。

08

项目表达

如果被问到项目中用过哪些设计模式,可以选择两三个最真实的例子深入讲,而不是一口气罗列十几个名称。推荐表达方式是:先说业务痛点,再说为什么选这个模式,然后说类之间如何协作,最后说收益和代价。例如用策略模式替代优惠规则的条件分支,收益是新增规则不改主流程,代价是类数量增加,需要通过命名、注册机制和测试来控制维护成本。

易错点

  • 只罗列设计模式名称,不解释它们分别解决什么变化点和维护问题。
  • 把所有条件分支都改成策略模式,忽略简单逻辑直接编码更清晰。
  • 把单例模式说成静态工具类,完全不讨论线程安全和生命周期管理。
  • 混淆代理、装饰器、适配器,只描述包一层对象而不说明设计意图。
  • 讲 Spring 用到设计模式时只背结论,不结合 Bean、AOP、事件和模板类。
  • 没有项目落地例子,答案停留在教材概念,缺少业务可信度。
  • 忽视过度设计风险,不说明类数量、排查链路和团队理解成本。
  • 把观察者模式等同于异步消息,忽略本地事件和同步通知也能体现该思想。

面试官追问

策略模式和工厂模式有什么区别?

策略模式关注一组可替换行为的封装,例如不同优惠算法或支付路由算法;工厂模式关注对象创建过程的封装,例如根据渠道创建对应策略对象。实际项目里二者经常组合使用,工厂负责找到策略,策略负责执行业务行为。

代理模式和装饰器模式怎么区分?

代理模式的重点是控制访问或增强调用链,比如事务、鉴权、远程调用和延迟加载;装饰器模式的重点是给对象动态叠加能力,比如缓存、压缩、加密。它们结构上都可能持有目标对象,但设计意图不同。

单例模式为什么不能随便用?

单例会引入全局状态,容易影响测试隔离、并发安全和对象生命周期管理。现代后端项目中更常见的做法是交给容器托管单例对象,而不是手写静态实例,这样依赖注入、销毁回调和替换测试实现都更容易。

责任链和策略模式都能消除 if else,应该怎么选?

如果一次请求只需要选择一个算法或规则执行,通常更适合策略模式;如果一次请求需要经过多个处理器依次校验、拦截、补充信息或决定是否中断,责任链更合适。选择时关键看业务是单点替换还是多步骤编排。

模板方法模式在后端项目里有什么真实场景?

模板方法适合主流程稳定、局部步骤变化的场景,例如文件导入、对账处理、报表生成、消息消费。基类固定校验、解析、处理、记录结果的流程,子类只实现差异步骤,可以减少重复代码并统一异常处理。

观察者模式和消息队列有什么关系?

观察者模式是一种发布订阅思想,强调事件产生者和事件消费者解耦;消息队列是这种思想在分布式系统里的常见基础设施实现。单体应用可用本地事件,跨服务或需要削峰、重试、异步解耦时更适合消息队列。