```html
📞 咨询热线:400-XXX-XXXX | 📧 邮箱:support@kaoacca.cn

设计模式精讲面试

深入理解23种设计模式,掌握架构设计精髓,从容应对大厂技术面试。单例模式、工厂模式、观察者模式... 一站式掌握核心考点。

核心设计模式精讲

创建型模式:对象的诞生艺术

创建型模式关注对象的创建过程,旨在将对象的创建与使用分离,降低系统耦合度。

① 单例模式 (Singleton)

核心定义:确保一个类只有一个实例,并提供一个全局访问点。

面试考点:懒汉式 vs 饿汉式、双重检查锁(DCL)、枚举单例、线程安全。

应用场景:Spring Bean默认单例、数据库连接池、配置中心。

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

② 工厂模式 (Factory)

核心定义:定义创建对象的接口,让子类决定实例化哪一个类。

面试考点:简单工厂、工厂方法、抽象工厂的区别;开闭原则的体现。

应用场景:JDBC Driver加载、MyBatis Mapper代理创建。

③ 建造者模式 (Builder)

核心定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

面试考点:链式调用、参数过多时的替代方案、Java StringBuilder源码。

结构型模式:类与对象的组合

结构型模式关注类和对象的组合,通过继承或组合来放大现有功能。

④ 适配器模式 (Adapter)

核心定义:将一个类的接口转换成客户希望的另外一个接口。

面试考点:类适配器 vs 对象适配器、Spring MVC HandlerAdapter。

⑤ 代理模式 (Proxy)

核心定义:为其他对象提供一种代理以控制对这个对象的访问。

面试考点:JDK动态代理 vs CGLIB、AOP底层原理、远程代理、虚拟代理。

⑥ 装饰器模式 (Decorator)

核心定义:动态地给一个对象添加一些额外的职责。

面试考点:Java IO流设计、Spring Security过滤器链。

行为型模式:对象间的通信

行为型模式关注对象之间的通信,封装系统中对象之间的相互作用。

⑦ 观察者模式 (Observer)

核心定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

面试考点:发布订阅模式区别、Spring Event机制、MQ解耦。

⑧ 策略模式 (Strategy)

核心定义:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

面试考点:消除多重if-else、Spring Validation、支付渠道选择。

⑨ 模板方法模式 (Template)

核心定义:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。

面试考点:钩子方法、Spring JdbcTemplate、Servlet生命周期。

高频面试真题解析

以下是面试官在考察设计模式时最常问到的问题,以及深度解答。

Q1: 为什么Spring框架中大量使用设计模式?请举例说明。

Spring框架是Java设计模式的集大成者。例如:

  • ① 工厂模式:BeanFactory用于创建和管理Bean实例。
  • ② 单例模式:Spring容器中Bean默认是单例的,通过singletonObjects Map实现。
  • ③ 代理模式:AOP底层通过JDK动态代理或CGLIB实现,增强业务逻辑。
  • ④ 模板方法模式:JdbcTemplate、RestTemplate等简化了资源管理和异常处理。
  • ⑤ 观察者模式:ApplicationEventPublisher和ApplicationListener实现事件驱动。

理解这些模式能帮助你更好地阅读Spring源码,并在实际开发中灵活运用。

Q2: 单例模式在多线程环境下如何保证线程安全?

保证单例线程安全主要有以下几种方式:

  • ① 饿汉式:类加载时即创建实例,天然线程安全,但可能浪费资源。
  • ② 懒汉式+ synchronized:简单但性能差,每次调用都加锁。
  • ③ 双重检查锁(DCL):先判断instance是否为null,不为null直接返回;为null再 synchronized,再次判断。需要 volatile 关键字防止指令重排。
  • ④ 静态内部类:利用类加载机制保证线程安全,推荐方式。
  • ⑤ 枚举:由JVM保证线程安全,防止反射和序列化破坏单例,最推荐方式。
Q3: 策略模式如何消除复杂的if-else?

使用策略模式结合工厂模式或Map映射可以优雅地消除if-else:

// 定义策略接口
public interface PaymentStrategy {
    void pay(double amount);
}
// 具体策略
public class AlipayStrategy implements PaymentStrategy {
    public void pay(double amount) { System.out.println("支付宝支付: " + amount); }
}
// 上下文/工厂
public class PaymentContext {
    private Map strategies = new HashMap<>();
    public PaymentContext() {
        strategies.put("alipay", new AlipayStrategy());
        strategies.put("wechat", new WechatPayStrategy());
    }
    public void execute(String type, double amount) {
        strategies.get(type).pay(amount);
    }
}

这样新增支付方式只需增加一个类并注册到Map中,符合开闭原则。

源码中的设计模式

Java IO流

装饰器模式的典型应用。例如 BufferedInputStream 装饰 FileInputStream,在不修改原有类的情况下增加缓冲功能。

Spring AOP

代理模式的应用。Spring通过动态代理为目标Bean创建代理对象,从而在方法执行前后织入横切逻辑(如事务管理、日志记录)。

MyBatis Mapper

工厂模式和代理模式。SqlSessionConfiguration创建MapperProxyFactory,MapperProxy实现InvocationHandler,动态生成Mapper接口实现。

Servlet Filter

责任链模式的应用。多个Filter按顺序执行,形成链式调用,每个Filter可以决定是否继续执行后续Filter或提前返回。

常见问题解答 (FAQ)

Q: 学习设计模式的最佳顺序是什么?

建议按照创建型→结构型→行为型的顺序学习。首先掌握单例模式、工厂模式、建造者模式,这些在实际开发中最常用。然后是代理模式、装饰器模式。最后是观察者、策略等行为型模式。

Q: 设计模式在实际项目中真的有用吗?还是只是为了面试?

设计模式绝非只是为了面试。它们是前人总结的最佳实践,能帮助你编写出高内聚、低耦合、易扩展、易维护的代码。例如,使用策略模式可以避免大量的if-else,使用工厂模式可以简化对象创建逻辑。在实际工作中,理解设计模式能让你更快速地阅读和理解开源框架源码。

Q: 如何判断一个场景应该使用哪种设计模式?

关键看需求:

  • ① 需要创建对象且解耦?→ 工厂模式、建造者模式。
  • ② 需要保证唯一实例?→ 单例模式。
  • ③ 需要扩展功能而不修改原类?→ 装饰器模式。
  • ④ 需要动态替换算法?→ 策略模式。
  • ⑤ 需要一对多通知?→ 观察者模式。

多读开源框架源码,观察它们如何使用设计模式解决实际问题,是提升的关键。

```
斌知网
蜀ICP备2026017620号-5