设计模式及其应用场景总结
以下是常见的设计模式及其应用场景的总结,分为 创建型、结构型 和 行为型 三类,并附以实际应用示例(含Java框架中的典型应用):
一、创建型模式
解决对象创建过程的复杂性,解耦对象的使用和实例化方式。
1. 单例模式 (Singleton)
- 目的:确保一个类仅有一个实例,并提供全局访问点。
- 场景:
- 全局配置(如数据库连接池、日志对象)。
- Spring 中的 Bean 默认单例(由 IoC 容器管理)。
- 示例:
public class Singleton { private static Singleton instance; private Singleton() {} // 私有构造 public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2. 工厂方法 (Factory Method)
- 目的:定义一个创建对象的接口,但由子类决定实例化哪个类。
- 场景:
- 需要根据条件动态创建对象(如根据类型创建不同的数据库连接驱动)。
- Spring 的
BeanFactory
是工厂模式的典型实现。
- 示例:
public interface ShapeFactory { Shape createShape(); } public class CircleFactory implements ShapeFactory { @Override public Shape createShape() { return new Circle(); } }
3. 抽象工厂 (Abstract Factory)
- 目的:提供一个接口,创建多个相关或依赖对象的家族。
- 场景:
- GUI 组件库(如 Windows/Mac 风格的按钮、文本框组合)。
- JDBC 的
Connection
接口(不同数据库返回不同类型的Statement
)。
- 示例:
public interface GUIFactory { Button createButton(); TextBox createTextBox(); } public class WindowsFactory implements GUIFactory { /*...*/ } public class MacFactory implements GUIFactory { /*...*/ }
4. 建造者模式 (Builder)
- 目的:分步构建复杂对象,分离对象的构造与表示。
- 场景:
- 创建复杂配置对象(例如
StringBuilder
、Lombok 的@Builder
)。
- 创建复杂配置对象(例如
- 示例:Java 中的
StringBuilder
:StringBuilder sb = new StringBuilder(); sb.append("Hello").append(" World"); String result = sb.toString();
5. 原型模式 (Prototype)
- 目的:通过克隆现有对象来创建新对象,优化性能。
- 场景:
- 对象创建成本高(如数据库查询结果缓存后的多次复制)。
- Java 的
Cloneable
接口支持对象克隆。
- 示例:
public class Prototype implements Cloneable { @Override protected Prototype clone() throws CloneNotSupportedException { return (Prototype) super.clone(); } }
二、结构型模式
关注类和对象的组合,提高系统扩展性。
1. 适配器模式 (Adapter)
- 目的:转换接口,使不兼容的类协同工作。
- 场景:
- 旧接口适配新需求(如
InputStreamReader
适配字节流到字符流)。
- 旧接口适配新需求(如
- 示例:Java IO 中的适配器:
InputStream input = new FileInputStream("file.txt"); Reader reader = new InputStreamReader(input); // 字节流适配到字符流
2. 装饰器模式 (Decorator)
- 目的:动态地为对象添加额外职责,避免继承导致类膨胀。
- 场景:
- Java IO 流的扩展(如
BufferedInputStream
包装InputStream
)。
InputStream input = new FileInputStream("file.txt"); InputStream buffered = new BufferedInputStream(input); // 添加缓冲功能
- Java IO 流的扩展(如
3. 代理模式 (Proxy)
- 目的:为其他对象提供一种代理以控制访问。
- 场景:
- 延迟加载(Hibernate 的懒加载)。
- AOP 实现(如 Spring 的动态代理)。
- 示例:JDK 动态代理:
public interface UserService { void save(); } public class UserServiceImpl implements UserService { /*...*/ } // 代理类通过InvocationHandler增强目标方法 UserService proxy = (UserService) Proxy.newProxyInstance(...);
4. 组合模式 (Composite)
- 目的:将对象组合成树形结构表示“整体-部分”层次结构。
- 场景:
- 文件系统(文件夹和文件的统一处理)。
- GUI 组件(窗口包含多个子控件)。
- 示例:
public abstract class Component { public void add(Component c) {} // 叶子节点可能不支持此方法 public abstract void render(); } public class Folder extends Component { /* 包含子组件 */ } public class File extends Component { /*...*/ }
5. 外观模式 (Facade)
- 目的:为子系统提供简化接口。
- 场景:
- SLF4J 作为日志门面,屏蔽底层 Log4j、Logback 实现。
- Spring MVC 的
DispatcherServlet
统一处理请求分发。
三、行为型模式
关注对象之间的交互和职责分配。
1. 策略模式 (Strategy)
- 目的:定义一系列算法,使其可相互替换。
- 场景:
- 支付方式选择(微信、支付宝、银行卡等)。
- Java 的
Comparator
接口(可自定义排序策略)。
- 示例:
public interface PaymentStrategy { void pay(int amount); } public class WechatPay implements PaymentStrategy { /*...*/ } public class Alipay implements PaymentStrategy { /*...*/ }
2. 观察者模式 (Observer)
- 目的:定义对象间的一对多依赖,当对象状态改变时通知所有依赖者。
- 场景:
- 事件驱动(如 GUI 中的按钮点击事件)。
- Spring 的
ApplicationEvent
和ApplicationListener
。
- 示例:Java 内置的
Observable
和Observer
:public class Subject extends Observable { public void change() { setChanged(); notifyObservers(); // 通知所有观察者 } }
3. 模板方法 (Template Method)
- 目的:定义算法骨架,将某些步骤延迟到子类实现。
- 场景:
- Spring 中的
JdbcTemplate
,提供数据库操作流程,子类实现具体 SQL。
public abstract class JdbcTemplate { public final void execute() { connect(); query(); // 抽象方法,由子类实现 close(); } protected abstract void query(); }
- Spring 中的
4. 责任链模式 (Chain of Responsibility)
- 目的:将请求的发送者和接收者解耦,使多个对象都有机会处理请求。
- 场景:
- Web 过滤器链(如 Spring Security 的
FilterChain
)。
public interface Filter { void doFilter(Request request, Response response, FilterChain chain); }
- Web 过滤器链(如 Spring Security 的
5. 状态模式 (State)
- 目的:允许对象在内部状态改变时改变行为。
- 场景:
- 订单状态流转(待付款、已发货、已签收等)。
- 示例:
public interface OrderState { void handle(Order order); } public class PendingPaymentState implements OrderState { /*...*/ }
四、实际开发中的选择建议
- 解耦对象创建:单例、工厂、建造者。
- 灵活扩展功能:装饰器、代理。
- 算法动态替换:策略、责任链。
- 组件间通信:观察者、中介者。
- 处理复杂结构:组合、适配器。
设计模式的核心是 “封装变化” 和 “面向接口编程”,避免为了模式而模式,结合具体业务灵活运用。