跳至主要內容

设计模式面试

钝悟...大约 12 分钟设计设计模式设计设计模式面试

设计模式面试

综合

【简单】什么是设计模式?为什么需要设计模式?

设计模式是软件设计中常见问题的典型解决方案。

设计模式是针对软件设计中常见问题的、可重用解决方案模板最佳实践

模式是针对软件设计中常见问题的解决方案工具箱, 它们定义了一种让你的团队能更高效沟通的通用语言。

【中等】设计模式可以分为哪几类?一共有多少种主流的设计模式?

一共有 23 种主流设计模式

创建型模式

【中等】单例模式有哪几种实现?如何保证线程安全?

线程不安全:如果两个线程同时执行到 if (instance == null) 判断,且都发现为 null,则会创建两个实例

public class Singleton {
    private static Singleton instance;

    // 私有构造函数,防止外部 new
    private Singleton() {}

    // 全局访问点
    public static Singleton getInstance() {
        if (instance == null) { // 线程不安全的发生点
            instance = new Singleton();
        }
        return instance;
    }
}

【中等】什么是简单工厂模式?有哪些经典的应用场景?

简单工厂模式由一个工厂类统一负责对象的创建,根据传入的参数决定具体创建哪种产品。 客户端无需关心创建细节,实现创建与使用的分离。

三大角色

  • 工厂 (Factory):核心,包含创建逻辑的静态方法。
  • 抽象产品 (Product):所有具体产品的父类或接口,定义公共方法。
  • 具体产品 (Concrete Product):工厂创建的目标,实现抽象产品接口。

经典应用场景

  • JDKCalendar.getInstance(), NumberFormat.getInstance()
  • 日志框架LoggerFactory.getLogger()
  • 数据库连接DriverManager.getConnection(), 连接池获取连接
  • 加密解密KeyGenerator.getInstance("AES")
  • GUI 工具包:跨平台创建控件

优缺点

  • 优点解耦(创建与使用分离)、职责清晰(代码易于维护)。
  • 缺点违反开闭原则(新增产品必须修改工厂逻辑),工厂类会变得臃肿。

【中等】什么是工厂模式?有哪些经典的应用场景?

工厂模式将对象的创建过程封装起来,与使用它的代码解耦。客户端不关心对象如何被创建,只关心如何使用。

三种工厂模式对比

模式核心思想优点缺点适用场景
简单工厂一个“万能”工厂,根据参数创建一种类型的不同产品。结构简单,封装创建过程。违反开闭原则,新增产品需修改工厂。产品类型少且稳定(如计算器运算)。
工厂方法定义一个创建接口,让子类工厂决定实例化哪一种产品符合开闭原则,易于扩展新产品。类数量增多(每产品一工厂)。需要频繁扩展新产品个体(如新增日志输出源)。
抽象工厂一个工厂创建一整套(一族) 相关的产品。保证产品族兼容性,切换整套产品方便。难以支持新增产品种类需要创建一组有关联的产品(如整套跨平台 UI 控件)。

经典应用场景

  • JDK/框架级应用

    • Calendar.getInstance(), DriverManager.getConnection()简单工厂
    • Collection.iterator()工厂方法 - 每个集合生产自己的迭代器)
    • Spring IOC 容器:终极的工厂,getBean() 是核心工厂方法。
  • 工具库

    • 日志框架(SLF4J):getLogger() 是工厂方法,绑定不同实现(Logback, Log4j)就是具体工厂。
    • JDBCConnection 是抽象工厂,其 createStatement() 是工厂方法。
  • 业务系统

    • 支付系统PaymentFactory 下有 AliPayFactory, WeChatPayFactory工厂方法),每个工厂生产一套支付产品(支付、退款、查询)。
    • UI 主题/游戏风格DarkThemeFactoryLightThemeFactory 分别生产一套 dark/light 风格的按钮、对话框、菜单(抽象工厂)。

一句话总结

  • 简单工厂:怎么造?我一个厂子全包了!(产品扩展麻烦
  • 工厂方法:造什么?我开分厂,每个分厂专精一样!(个体扩展方便
  • 抽象工厂:要配套!我开集团,每个集团生产一套组合产品!(整套切换方便

结构型模式

【中等】什么是代理模式?有哪些经典的应用场景?

代理模式通过一个“中介”(代理对象)来控制和管理对另一个对象(真实对象)的访问。代理与真实对象实现相同的接口,使客户端无感知。

典型应用场景

代理类型核心目的经典应用场景
RPC隐藏对象不在本地的事实,提供本地代表。RPC 框架(如 gRPC, Dubbo)、Java RMI。客户端调用的 Stub 就是代理。
AOP在访问前后添加额外操作,增强功能。Spring AOP(日志、事务)、ORM 懒加载(Hibernate/MyBatis)、缓存。

代理模式的核心价值在于:在不修改原始对象的情况下,通过代理间接访问,从而实现权限控制、功能增强或性能优化。它是 Spring AOP 等技术的基石。

行为型模式

【中等】什么是策略模式?有哪些经典的应用场景?

策略模式定义一族算法,封装每个算法,并使它们可以互相替换。策略模式让算法的变化独立于使用它的客户端,实现“做什么”和“怎么做”的分离。

三大核心角色

  • 上下文 (Context):持有策略的引用,负责对接客户端,并委托策略执行。
  • 抽象策略 (Strategy):策略家族的抽象(接口或抽象类),定义了所有策略必须实现的方法。
  • 具体策略 (Concrete Strategy):实现了抽象策略接口的具体算法。

核心价值与优点

  • 消除条件判断:用组合替代大量 if-elseswitch,使代码更清晰。
  • 符合开闭原则新增策略只需添加新类,无需修改上下文或已有代码,扩展性极佳。
  • 算法复用与独立:算法可以独立变化和复用。

经典应用场景

  • 电商促销:无缝切换折扣、立减、满减等不同计价策略。
  • 支付系统:灵活支持支付宝、微信、银联等不同支付方式。
  • 排序比较:Java 中的 Comparator 接口是典范,传入不同比较器实现不同排序规则。
  • 导航规划:根据用户选择(最短时间、最短距离、避开收费)计算不同路线。
  • 游戏 AI:角色动态切换攻击(近战、远程)或移动(行走、奔跑)策略。

当代码中出现大量条件判断来选择不同行为时,就是使用策略模式的最佳时机。它通过“组合”和“委托”将算法灵活地包装起来,便于任意替换和扩展。

【中等】什么是观察者模式?有哪些经典的应用场景?

观察者模式实现一对多的依赖关系(又称发布-订阅模型),当一个对象(主题)状态改变时,它能自动通知并更新所有依赖它的对象(观察者)。

两大核心角色

  • 主题 (Subject):维护一个观察者列表,提供注册、移除和通知的方法。
  • 观察者 (Observer):定义一个接收通知的更新接口。

核心价值与优点

  • 松耦合:主题与观察者互不知晓对方细节,仅通过接口交互,独立性极强。
  • 动态联动:支持在运行时动态地添加或删除观察者,非常灵活。
  • 广播通信:主题的一次调用可以触发所有观察者的更新。

经典应用场景

  • GUI 事件处理:按钮、鼠标等控件(主题)的事件监听器(观察者)。
  • 发布-订阅消息队列:Kafka、RabbitMQ 等中间件(分布式观察者模式)。
  • 前端响应式框架:Vue/React 的响应式系统(数据变 → 视图自动更新)。
  • MVC 架构:模型(Model)数据变化 → 自动通知视图(View)更新。
  • 社交媒体推送:你关注的人(主题)发帖 → 你(观察者)的时间线更新。

【中等】什么是模板方法模式?有哪些经典的应用场景?

模板方法模式中,父类定义算法骨架(模板方法),子类实现具体步骤。实现“流程固定,细节可变”,确保逻辑顺序一致的同时允许特定步骤个性化。

两大核心角色

  • 抽象类 (Abstract Class)
    • 包含一个 final 模板方法(定义不可更改的算法流程)。
    • 包含抽象方法(必须由子类实现)、具体方法(通用步骤)和钩子方法(可选步骤,提供额外扩展点)。
  • 具体子类 (Concrete Class)仅负责实现父类定义的抽象方法,填充算法骨架中的具体步骤。

核心价值与优点

  • 代码复用:将公共流程提升至父类,避免子类代码重复。
  • 反向控制(好莱坞原则):父类控制流程,“调用”子类,而非子类调用父类。
  • 便于扩展与维护:新增行为只需增加子类;修改流程只需改动父类一处。

经典应用场景

  • 框架设计:是框架的基石,定义扩展流程。
    • Java ServletHttpServlet.service() 是模板方法,调用开发者重写的 doGet()/doPost()
    • Spring JdbcTemplate:固定了数据库操作流程(取连接、执行、释放资源),开发者提供 SQL 和结果处理逻辑。
  • 单元测试JUnitTestCase 定义了 setUp() → testMethod() → tearDown() 的标准流程。
  • 生命周期管理Android Activity 的生命周期方法调用顺序由系统框架固定。
  • 通用算法:Java 集合框架的 AbstractList 提供了基于 get()size() 的通用算法实现。

【中等】什么是责任链模式?有哪些经典的应用场景?

责任链模式将处理请求的对象连成一条链,请求沿链传递,直到有一个对象处理它为止。实现“谁有空谁处理”的“踢皮球”机制。

两大核心角色

  1. 处理者 (Handler):定义处理请求的接口,并持有下一个处理者的引用。
  2. 具体处理者 (Concrete Handler):实现处理接口。能处理则处理,不能处理则转发给下一个。

核心价值与优点

  • 解耦请求发送者无需知道谁处理请求,只需向链首提交。
  • 动态灵活:可动态增删或调整处理者顺序,灵活改变处理流程。
  • 职责清晰:每个处理者只需关注自己的职责范围。

经典应用场景

  • 审批流程:多级审批(如报销、请假),根据金额、类型等条件由不同级别领导处理。
  • Web 过滤器/拦截器Java Servlet FilterChainSpring Interceptor,请求依次通过权限校验、日志、编码等过滤器。
  • 异常处理:Java 的 try-catch 块就是责任链,沿调用栈寻找匹配的异常处理器。
  • 事件冒泡:UI 编程中(如浏览器 DOM),事件从子元素向父元素逐级传播处理。
  • 日志系统:日志消息根据级别(DEBUG, ERROR)被传递到不同的输出端(控制台、文件)。

参考资料

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.7