摘要:
本文系统解析Java开发中最常用的7种设计模式及其在面试中的核心考点,涵盖单例模式、工厂模式、观察者模式等高频模式。结合代码实现、应用场景对比和框架集成实战,深入探讨设计模式在微服务架构、代码优化、Spring框架中的典型应用。提供从开发实践到面试准备的完整指南,助力开发者提升代码质量与系统设计能力。
📚 高频设计模式分类表
模式名称 |
分类 |
核心思想 |
典型应用场景 |
单例模式 |
创建型 |
全局唯一实例控制,避免资源重复消耗 |
配置管理、连接池、日志系统 |
工厂模式 |
创建型 |
封装对象创建过程,隔离客户端与具体实现 |
多支付渠道适配、跨平台组件生成 |
观察者模式 |
行为型 |
松耦合的事件通知机制,实现一对多状态同步 |
订单状态变更、Spring事件驱动 |
装饰器模式 |
结构型 |
动态扩展对象功能,避免继承导致的类爆炸 |
Java IO流体系、功能增强场景 |
代理模式 |
结构型 |
控制对象访问,增强核心逻辑 |
AOP切面、RPC调用、权限控制 |
策略模式 |
行为型 |
算法族封装,支持运行时动态切换 |
支付方式选择、优惠规则计算 |
模板方法 |
行为型 |
定义算法骨架,子类实现具体步骤 |
工作流引擎、标准化ETL流程 |
一、开发常用设计模式(按使用频率排序)
1. 单例模式
应用场景
- 全局配置管理(如Spring的Environment对象)
- 数据库连接池(避免重复创建连接)
- 日志管理器(统一日志输出通道)
核心实现
// 双重检查锁(DCL)实现
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;
}
}
开发价值
- 节省JVM内存开销(减少重复对象创建)
- 保证全局状态一致性(如配置信息)
2. 工厂模式
应用场景
- 支付系统多通道切换(微信/支付宝/银联)
- 跨平台UI组件生成(Android/iOS适配)
代码示例
// 抽象工厂实现多数据库驱动
public interface DatabaseDriver {
Connection createConnection();
}
public class MySQLDriver implements DatabaseDriver { ... }
public class OracleDriver implements DatabaseDriver { ... }
public class DriverFactory {
public static DatabaseDriver getDriver(String dbType) {
switch(dbType) {
case "mysql": return new MySQLDriver();
case "oracle": return new OracleDriver();
default: throw new IllegalArgumentException();
}
}
}
3. 观察者模式
应用场景
- 电商订单状态变更通知(短信/邮件/App推送)
- Spring事件驱动模型(@EventListener注解)
代码示例
// 自定义实现
public class OrderSubject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) {
observers.add(o);
}
public void notifyObservers(String message) {
observers.forEach(o -> o.update(message));
}
}
// 使用示例
orderSubject.addObserver(new SmsObserver());
orderSubject.notifyObservers("订单已发货");
4. 装饰器模式
典型应用
- Java IO流体系(如BufferedInputStream增强基础流)
- Spring Security过滤器链(功能动态叠加)
开发优势
- 避免继承导致的类爆炸问题
- 支持运行时动态扩展对象功能
代码示例
// 1. 数据读取接口
interface DataReader {
String readData();
void writeData(String content);
}
// 2. 基础实现类
class FileReader implements DataReader {
@Override
public String readData() {
return "Original file data";
}
@Override
public void writeData(String content) {
System.out.println("FileWriter: Writing -> " + content);
}
}
// 3. 缓冲装饰器
class BufferedFileReader implements DataReader {
private final DataReader wrappee;
public BufferedFileReader(DataReader reader) {
this.wrappee = reader;
}
@Override
public String readData() {
String data = wrappee.readData();
return "[BUFFERED] " + data.toUpperCase();
}
@Override
public void writeData(String content) {
wrappee.writeData("[BUFFERED] " + content);
}
}
// 4. 加密装饰器
class EncryptionDecorator implements DataReader {
private final DataReader wrappee;
public EncryptionDecorator(DataReader reader) {
this.wrappee = reader;
}
@Override
public String readData() {
String encrypted = wrappee.readData();
return decrypt(encrypted);
}
@Override
public void writeData(String content) {
wrappee.writeData(encrypt(content));
}
private String encrypt(String data) {
return "🔒" + data + "🔒"; // 模拟加密
}
private String decrypt(String data) {
return data.replace("🔒", ""); // 模拟解密
}
}
// 5. 使用示例(新增main方法)
public class DecoratorDemo {
public static void main(String[] args) {
// 基础文件读写
DataReader simpleReader = new FileReader();
System.out.println("基础读取: " + simpleReader.readData());
simpleReader.writeData("Hello World");
System.out.println("\n======== 装饰器组合使用 ========");
// 组合装饰器:加密 + 缓冲
DataReader decoratedReader = new BufferedFileReader(
new EncryptionDecorator(
new FileReader()
)
);
// 读取时:加密 -> 解密 -> 缓冲处理
System.out.println("读取装饰数据: " + decoratedReader.readData());
// 写入时:缓冲处理 -> 加密存储
decoratedReader.writeData("Decorator Pattern");
}
}
/* 执行结果:
基础读取: Original file data
FileWriter: Writing -> Hello World
5. 代理模式
应用场景
- Spring AOP切面编程(@Transactional事务管理)
- RPC远程方法调用(网络通信屏蔽)
技术对比
代理类型 |
实现原理 |
适用场景 |
JDK动态代理 |
基于接口反射生成代理类 |
Spring默认AOP实现 |
CGLIB |
基于类继承生成子类代理 |
代理无接口的类 |
代码示例
// 控制对象访问,AOP切面基础
interface Image {
void display();
}
class RealImage implements Image { /* 真实图片加载 */ }
// 静态代理
class ImageProxy implements Image {
private RealImage realImage;
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage();
}
preProcess();
realImage.display();
postProcess();
}
private void preProcess() { /* 预处理 */ }
private void postProcess() { /* 后处理 */ }
}
// JDK动态代理
class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) { this.target = target; }
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用方法: " + method.getName());
return method.invoke(target, args);
}
}
6. 策略模式
典型用例
- 支付渠道选择算法(权重计算/风控策略)
- 优惠券计算规则切换(满减/折扣/积分抵扣)
代码示例
// 算法族封装,消除if-else判断
interface DiscountStrategy {
double applyDiscount(double price);
}
class FullReductionStrategy implements DiscountStrategy {
@Override // 满100减20
public double applyDiscount(double price) {
return price >= 100 ? price -20 : price;
}
}
class Context {
private DiscountStrategy strategy;
public Context(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double executeStrategy(double price) {
return strategy.applyDiscount(price);
}
}
7. 模板方法模式
应用场景
- 工作流引擎(审批流程标准化)
- JdbcTemplate数据操作(定义SQL执行通用流程)
代码示例
public abstract class ReportTemplate {
// 模板方法(final防止流程篡改)
public final void generateReport() {
fetchData();
formatData();
if (needExport()) export();
}
protected abstract void fetchData();
protected abstract void formatData();
}
二、面试高频考点设计模式
设计模式 |
典型面试问题 |
关联原理考察点 |
单例模式 |
1. 为什么双重检查锁需要volatile? 2. 枚举单例如何防止反射攻击? |
类加载机制、内存可见性、反射原理 |
工厂模式 |
1. 工厂方法与抽象工厂的区别? 2. Spring BeanFactory如何实现延迟加载? |
开闭原则、IoC容器原理 |
装饰器模式 |
1. 与代理模式的核心差异? 2. 为什么Java IO采用装饰器而非继承? |
组合优于继承原则、设计扩展性 |
代理模式 |
1. JDK动态代理和CGLIB实现原理? 2. Spring AOP默认使用哪种代理? |
字节码增强技术、接口与继承差异 |
三、设计模式综合应用建议
1. 架构级应用
- 微服务场景
▸ 适配器模式:统一对接第三方物流系统接口
▸ 门面模式:封装支付网关的复杂调用流程(加密/验签/重试)
2. 代码优化技巧
// 建造者模式替代多参数构造器
public class User {
private String name;
private int age;
// ...其他字段
public static class Builder {
private String name;
private int age;
public Builder name(String name) { this.name = name; return this; }
public Builder age(int age) { this.age = age; return this; }
public User build() { return new User(this); }
}
}
// 使用示例
User user = new User.Builder().name("Alice").age(25).build();
3. Spring框架设计模式集
模式名称 |
应用场景 |
实现示例 |
模板方法 |
JdbcTemplate.execute() |
定义SQL执行通用流程 |
代理模式 |
@Transactional注解 |
AOP事务管理 |
工厂模式 |
BeanFactory.getBean() |
Bean生命周期管理 |
四、分布式场景专项
1. 服务熔断与策略模式
- 架构实践:Hystrix的熔断算法如何通过策略模式实现
// Hystrix熔断器状态切换策略
public interface CircuitBreakerStrategy {
boolean allowRequest();
void markSuccess();
}
// 滑动窗口策略实现
public class RollingWindowStrategy implements CircuitBreakerStrategy { ... }
2. 分布式锁与代理模式
- 模式变体:基于注解+AOP实现声明式分布式锁(参考Redisson源码)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
String lockKey();
int expireTime() default 30;
}
// AOP切面实现
@Aspect
public class LockAspect {
@Around("@annotation(lock)")
public Object around(ProceedingJoinPoint pjp, DistributedLock lock) {
RLock rLock = redisson.getLock(lock.lockKey());
try {
rLock.lock(lock.expireTime(), TimeUnit.SECONDS);
return pjp.proceed();
} finally {
rLock.unlock();
}
}
}
📝 总结
面试核心结论:
- 单例/工厂模式是解决对象创建复杂度的利器
- 观察者/策略模式显著提升系统扩展性
- 模板方法/装饰器模式优化代码复用结构
系统级设计启示
- 模式演进思维:
- 单例模式在分布式场景下需升级为 全局协调服务(如ZooKeeper/Redis分布式锁)
- 工厂模式在微服务架构中需结合 服务发现机制(如Spring Cloud Feign动态代理)
- 扩展性决策矩阵:
- 观察者模式在 10万级事件/秒 场景需升级为 异步消息队列(Kafka vs RabbitMQ吞吐量对比)
- 策略模式需支持 动态配置热更新(结合Nacos/Apollo配置中心)
- 反模式预警:
- 单例模式滥用导致 跨服务状态不一致(案例:电商库存超卖事故分析)
- 装饰器模式过度包装引发 调用链性能劣化(火焰图定位方法)