从理论到框架实践
设计模式是软件开发中经过验证的最佳实践,能够有效解决代码复用、解耦和扩展性问题。本文将深入解析创建型、结构型、行为型三大类中最常用的设计模式,提供完整Java代码示例,并结合Spring、MyBatis等主流框架的源码场景,展示设计模式的工业级应用。
一、创建型模式:对象实例化的艺术
1.1 单例模式(Singleton Pattern)
定义:确保一个类仅有一个实例,并提供全局访问点。
核心价值:控制资源访问、减少对象创建开销(如数据库连接池、日志对象)。
代码实现:五种经典单例
| 实现方式 | 线程安全 | 延迟加载 | 防止反射/序列化 | 代码示例 |
|---|---|---|---|---|
| 饿汉式 | ✅ 天然安全 | ❌ 类加载时初始化 | ❌ 不能 | public class EagerSingleton { private static final EagerSingleton INSTANCE = new EagerSingleton(); private EagerSingleton() {} public static EagerSingleton getInstance() { return INSTANCE; }} |
| 懒汉式(加锁) | ✅ 方法级synchronized | ✅ 首次调用时初始化 | ❌ 不能 | public class LazySingleton { private static LazySingleton instance; private LazySingleton() {} public static synchronized LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; }} |
| 双重检查锁(DCL) | ✅ volatile+同步块 | ✅ 延迟初始化 | ❌ 不能 | public class DCLSingleton { private static volatile DCLSingleton instance; private DCLSingleton() {} public static DCLSingleton getInstance() { if (instance == null) { synchronized (DCLSingleton.class) { if (instance == null) { instance = new DCLSingleton(); } } } return instance; }} |
| 静态内部类 | ✅ JVM类加载机制 | ✅ 内部类加载时初始化 | ❌ 不能 | public class InnerClassSingleton { private InnerClassSingleton() {} private static class Holder { private static final InnerClassSingleton INSTANCE = new InnerClassSingleton(); } public static InnerClassSingleton getInstance() { return Holder.INSTANCE; }} |
| 枚举单例 | ✅ JVM保证 | ❌ 枚举类加载时初始化 | ✅ 天然防止 | public enum EnumSingleton { INSTANCE; public void doSomething() { System.out.println("Singleton method called"); }} |
框架应用:Spring中的单例实现
Spring容器默认对Bean采用单例模式,核心实现位于DefaultSingletonBeanRegistry类,通过三级缓存解决循环依赖问题:
- 一级缓存(singletonObjects):存储完全初始化的单例Bean
- 二级缓存(earlySingletonObjects):存储提前暴露的未完全初始化Bean
- 三级缓存(singletonFactories):存储Bean工厂,用于生成代理对象
源码关键逻辑:
// DefaultSingletonBeanRegistry.java
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 一级缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); // 二级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject(); // 从工厂获取对象(可能是代理)
this.earlySingletonObjects.put(beanName, singletonObject); // 放入二级缓存
this.singletonFactories.remove(beanName); // 移除三级缓存
}
}
}
}
return singletonObject;
}
1.2 工厂模式(Factory Pattern)
定义:通过工厂接口封装对象创建逻辑,使客户端无需关注具体实现类。
类型:简单工厂、工厂方法、抽象工厂。
代码实现:工厂方法模式
// 产品接口
interface Shape { void draw(); }
// 具体产品
class Circle implements Shape { @Override public void draw() { System.out.println("Drawing Circle"); } }
class Rectangle implements Shape { @Override public void draw() { System.out.println("Drawing Rectangle"); } }
// 工厂接口
interface ShapeFactory { Shape getShape(); }
// 具体工厂
class CircleFactory implements ShapeFactory { @Override public Shape getShape() { return new Circle(); } }
class RectangleFactory implements ShapeFactory { @Override public Shape getShape() { return new Rectangle(); } }
// 使用示例
public class FactoryDemo {
public static void main(String[] args) {
ShapeFactory factory = new CircleFactory();
Shape shape = factory.getShape();
shape.draw(); // 输出: Drawing Circle
}
}
框架应用:Spring的Bean工厂体系
Spring的IoC容器核心是工厂模式的实现,主要接口和类:
- BeanFactory:基础工厂接口,定义
getBean()等方法,实现类如XmlBeanFactory(已过时) - ApplicationContext:继承BeanFactory,提供事件传播、国际化等增强功能,实现类如
ClassPathXmlApplicationContext、AnnotationConfigApplicationContext - FactoryBean:自定义Bean创建逻辑的接口,例如
DataSourceFactoryBean用于创建数据库连接池
示例:通过FactoryBean创建复杂对象
public class DataSourceFactoryBean implements FactoryBean<DataSource> {
private String url;
private String username;
private String password;
@Override
public DataSource getObject() throws Exception {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
return new HikariDataSource(config); // 自定义连接池创建逻辑
}
@Override
public Class<?> getObjectType() { return DataSource.class; }
}
// Spring配置
@Configuration
public class AppConfig {
@Bean
public DataSourceFactoryBean dataSource() {
DataSourceFactoryBean factory = new DataSourceFactoryBean();
factory.setUrl("jdbc:mysql://localhost:3306/test");
factory.setUsername("root");
factory.setPassword("123456");
return factory;
}
}
二、结构型模式:对象组合的设计
2.1 装饰器模式(Decorator Pattern)
定义:动态给对象添加额外功能,不改变其原有结构。
核心价值:功能扩展灵活(比继承更轻量),解决“类爆炸”问题。
代码实现:IO流中的装饰器
// 抽象构件
interface DataSource { void writeData(String data); }
// 具体构件(被装饰对象)
class FileDataSource implements DataSource {
private String filename;
public FileDataSource(String filename) { this.filename = filename; }
@Override
public void writeData(String data) { System.out.println("写入原始数据到文件: " + data); }
}
// 装饰器抽象类
abstract class DataSourceDecorator implements DataSource {
protected DataSource wrappee;
public DataSourceDecorator(DataSource source) { this.wrappee = source; }
@Override
public void writeData(String data) { wrappee.writeData(data); }
}
// 具体装饰器(加密功能)
class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) { super(source); }
@Override
public void writeData(String data) {
String encrypted = encrypt(data); // 加密逻辑
super.writeData(encrypted);
}
private String encrypt(String data) { return Base64.getEncoder().encodeToString(data.getBytes()); }
}
// 使用示例
public class DecoratorDemo {
public static void main(String[] args) {
DataSource source = new FileDataSource("test.txt");
DataSource encryptedSource = new EncryptionDecorator(source);
encryptedSource.writeData("敏感数据"); // 输出: 写入原始数据到文件: U2Vuc2l0aXZlIERhdGE=
}
}
框架应用:MyBatis缓存模块
MyBatis的缓存体系完全基于装饰器模式,Cache接口为抽象构件,PerpetualCache为基础实现,其他装饰器动态添加功能:
- LruCache:最近最少使用策略(缓存淘汰)
- LoggingCache:输出缓存命中日志
- SynchronizedCache:同步锁(线程安全)
- SerializedCache:对象序列化存储
源码结构:
// 抽象构件
public interface Cache {
String getId();
void putObject(Object key, Object value);
Object getObject(Object key);
Object removeObject(Object key);
void clear();
}
// 具体构件(基础实现)
public class PerpetualCache implements Cache {
private final String id;
private final Map<Object, Object> cache = new HashMap<>(); // 核心存储结构
// 实现Cache接口方法...
}
// 装饰器:LruCache(最近最少使用淘汰)
public class LruCache implements Cache {
private final Cache delegate;
private final Map<Object, Object> keyMap; // 记录访问顺序
private Object eldestKey;
public LruCache(Cache delegate) {
this.delegate = delegate;
this.keyMap = new LinkedHashMap<>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
boolean tooBig = size() > 1024; // 超过容量时淘汰最久未使用
if (tooBig) eldestKey = eldest.getKey();
return tooBig;
}
};
}
// 实现Cache接口方法,通过delegate调用基础缓存...
}
2.2 适配器模式(Adapter Pattern)
定义:将一个类的接口转换成客户端期望的另一种接口,解决接口不兼容问题。
核心价值:复用现有类,无需修改源码即可适配新接口。
代码实现:类适配器与对象适配器
// 目标接口(客户端期望的接口)
interface Target { void request(); }
// 被适配者(现有接口)
class Adaptee { public void specificRequest() { System.out.println("特殊请求(被适配接口)"); } }
// 类适配器(通过继承)
class ClassAdapter extends Adaptee implements Target {
@Override
public void request() { super.specificRequest(); } // 适配调用
}
// 对象适配器(通过组合)
class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) { this.adaptee = adaptee; }
@Override
public void request() { adaptee.specificRequest(); } // 适配调用
}
// 使用示例
public class AdapterDemo {
public static void main(String[] args) {
Target classAdapter = new ClassAdapter();
classAdapter.request(); // 输出: 特殊请求(被适配接口)
Target objectAdapter = new ObjectAdapter(new Adaptee());
objectAdapter.request(); // 输出: 特殊请求(被适配接口)
}
}
框架应用:Spring MVC的HandlerAdapter
Spring MVC中,DispatcherServlet通过HandlerAdapter适配不同类型的处理器(Controller),使调用统一化:
- RequestMappingHandlerAdapter:适配
@Controller注解的处理器方法 - HttpRequestHandlerAdapter:适配实现
HttpRequestHandler接口的处理器 - SimpleControllerHandlerAdapter:适配实现
Controller接口的传统处理器
核心流程:
// DispatcherServlet核心代码
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = getHandler(request); // 获取处理器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 获取适配器
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler()); // 统一调用
// ...视图渲染
}
// HandlerAdapter接口
public interface HandlerAdapter {
boolean supports(Object handler); // 判断是否支持当前处理器
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
三、行为型模式:对象交互的策略
3.1 策略模式(Strategy Pattern)
定义:定义算法族,封装每个算法,使它们可互换。
核心价值:消除复杂条件判断,算法切换灵活。
代码实现:支付策略
// 策略接口
interface PaymentStrategy { void pay(double amount); }
// 具体策略
class AlipayStrategy implements PaymentStrategy {
@Override public void pay(double amount) { System.out.println("支付宝支付: " + amount + "元"); }
}
class WechatPayStrategy implements PaymentStrategy {
@Override public void pay(double amount) { System.out.println("微信支付: " + amount + "元"); }
}
// 上下文
class PaymentContext {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) { this.strategy = strategy; }
public void executePayment(double amount) { strategy.pay(amount); }
}
// 使用示例
public class StrategyDemo {
public static void main(String[] args) {
PaymentContext context = new PaymentContext();
context.setStrategy(new AlipayStrategy());
context.executePayment(100); // 输出: 支付宝支付: 100.0元
context.setStrategy(new WechatPayStrategy());
context.executePayment(200); // 输出: 微信支付: 200.0元
}
}
框架应用:Spring的资源访问策略
Spring的Resource接口定义资源访问策略,不同实现类适配不同资源类型:
- ClassPathResource:类路径资源
- FileSystemResource:文件系统资源
- UrlResource:URL资源
- ServletContextResource:Web应用资源
示例:
Resource resource = new ClassPathResource("application.properties"); // 类路径策略
InputStream in = resource.getInputStream(); // 统一接口访问
3.2 代理模式(Proxy Pattern)
定义:为对象提供代理,控制对原对象的访问。
核心价值:增强功能(如日志、事务)、延迟加载、权限控制。
代码实现:JDK动态代理与CGLIB代理
| 代理方式 | 实现原理 | 目标要求 | 性能特点 |
|---|---|---|---|
| JDK动态代理 | 实现InvocationHandler | 目标类需实现接口 | 创建快,执行慢 |
| CGLIB代理 | 继承目标类,修改字节码 | 无需接口,不能代理final类 | 创建慢,执行快 |
JDK动态代理示例:
// 目标接口
interface UserService { void update(); }
// 目标类
class UserServiceImpl implements UserService {
@Override public void update() { System.out.println("执行更新操作"); }
}
// 代理处理器
class LogProxy implements InvocationHandler {
private Object target;
public LogProxy(Object target) { this.target = target; }
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志: 方法执行前"); // 增强逻辑
Object result = method.invoke(target, args); // 调用目标方法
System.out.println("日志: 方法执行后");
return result;
}
}
// 使用示例
public class ProxyDemo {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
new Class[]{UserService.class},
new LogProxy(target)
);
proxy.update(); // 输出: 日志: 方法执行前 → 执行更新操作 → 日志: 方法执行后
}
}
框架应用:Spring AOP的代理机制
Spring AOP基于代理模式实现,默认规则:
- 目标类有接口 → 使用JDK动态代理(
JdkDynamicAopProxy) - 目标类无接口 → 使用CGLIB代理(
CglibAopProxy)
核心源码:
// DefaultAopProxyFactory.java
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config); // JDK代理
}
return new ObjenesisCglibAopProxy(config); // CGLIB代理
} else {
return new JdkDynamicAopProxy(config);
}
}
3.3 观察者模式(Observer Pattern)
定义:定义对象间一对多依赖,当主题状态变化时,所有观察者自动收到通知。
核心价值:解耦事件发布者与订阅者,支持动态扩展。
代码实现:自定义事件监听
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 观察者接口
interface Observer { void update(String message); }
// 具体主题
class NewsSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String message;
@Override public void registerObserver(Observer observer) { observers.add(observer); }
@Override public void removeObserver(Observer observer) { observers.remove(observer); }
@Override public void notifyObservers() {
for (Observer observer : observers) {
observer.update(message); // 通知所有观察者
}
}
public void setMessage(String message) {
this.message = message;
notifyObservers(); // 状态变化时触发通知
}
}
// 具体观察者
class UserObserver implements Observer {
private String name;
public UserObserver(String name) { this.name = name; }
@Override public void update(String message) {
System.out.println(name + "收到新闻: " + message);
}
}
// 使用示例
public class ObserverDemo {
public static void main(String[] args) {
NewsSubject subject = new NewsSubject();
subject.registerObserver(new UserObserver("张三"));
subject.registerObserver(new UserObserver("李四"));
subject.setMessage("设计模式专栏更新啦!"); // 输出: 张三收到新闻... 李四收到新闻...
}
}
框架应用:Spring事件机制
Spring基于观察者模式实现事件驱动模型,核心组件:
- ApplicationEvent:事件基类(如
ContextRefreshedEvent容器刷新事件) - ApplicationListener:观察者接口(或
@EventListener注解) - ApplicationEventPublisher:事件发布器(由
ApplicationContext实现)
示例:自定义事件
// 自定义事件
class UserRegisterEvent extends ApplicationEvent {
private String username;
public UserRegisterEvent(Object source, String username) {
super(source);
this.username = username;
}
public String getUsername() { return username; }
}
// 事件发布者
@Service
class UserService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void register(String username) {
// 业务逻辑: 用户注册
publisher.publishEvent(new UserRegisterEvent(this, username)); // 发布事件
}
}
// 事件监听器
@Service
class EmailListener {
@EventListener // 注解式监听
public void sendEmail(UserRegisterEvent event) {
System.out.println("给" + event.getUsername() + "发送欢迎邮件");
}
}
@Service
class CouponListener implements ApplicationListener<UserRegisterEvent> {
@Override // 接口式监听
public void onApplicationEvent(UserRegisterEvent event) {
System.out.println("给" + event.getUsername() + "发放优惠券");
}
}
四、责任链模式
4.1 模式定义与核心思想
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,其核心思想是将请求的发送者与接收者解耦,通过构建一条处理者对象链,使请求能够沿着链传递,直到被某个处理者处理或到达链尾。每个处理者只需关注自身职责范围内的请求,无需知道整体链结构,从而实现请求处理的动态组合与扩展。
4.2 代码示例:请假审批流程
以企业请假审批为例,展示责任链模式的实现:
// 请假请求类
class LeaveRequest {
private String employee;
private int days;
// 构造函数、getter
public LeaveRequest(String employee, int days) {
this.employee = employee;
this.days = days;
}
public int getDays() { return days; }
public String getEmployee() { return employee; }
}
// 抽象处理者
abstract class Approver {
protected Approver nextApprover;
public void setNextApprover(Approver next) {
this.nextApprover = next;
}
public abstract void processRequest(LeaveRequest request);
}
// 具体处理者:组长(处理≤3天)
class TeamLeader extends Approver {
@Override
public void processRequest(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.println("组长批准" + request.getEmployee() + "的" + request.getDays() + "天请假");
} else if (nextApprover != null) {
nextApprover.processRequest(request);
}
}
}
// 具体处理者:CTO(处理≤7天)
class CTO extends Approver {
@Override
public void processRequest(LeaveRequest request) {
if (request.getDays() <= 7) {
System.out.println("CTO批准" + request.getEmployee() + "的" + request.getDays() + "天请假");
} else if (nextApprover != null) {
nextApprover.processRequest(request);
}
}
}
// 具体处理者:CEO(处理所有请假)
class CEO extends Approver {
@Override
public void processRequest(LeaveRequest request) {
System.out.println("CEO批准" + request.getEmployee() + "的" + request.getDays() + "天请假");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Approver teamLeader = new TeamLeader();
Approver cto = new CTO();
Approver ceo = new CEO();
// 构建责任链:组长 → CTO → CEO
teamLeader.setNextApprover(cto);
cto.setNextApprover(ceo);
// 提交请求
teamLeader.processRequest(new LeaveRequest("张三", 5)); // CTO处理
teamLeader.processRequest(new LeaveRequest("李四", 10)); // CEO处理
}
}
4.3 框架应用场景
4.3.1 Spring Security过滤器链
Spring Security的核心机制基于责任链模式,通过FilterChainProxy管理一系列过滤器(Filter),每个过滤器专注于特定安全功能:
- UsernamePasswordAuthenticationFilter:处理表单登录
- CsrfFilter:防御跨站请求伪造
- FilterSecurityInterceptor:权限控制决策
执行流程:
- 请求进入
FilterChainProxy,按顺序经过过滤器链 - 每个过滤器判断是否处理当前请求(如登录请求由
UsernamePasswordAuthenticationFilter处理) - 处理完成后通过
chain.doFilter()传递给下一个过滤器
关键代码片段:
// 自定义过滤器示例
public class CustomLoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// 处理逻辑(如记录请求日志)
System.out.println("Request URI: " + ((HttpServletRequest) request).getRequestURI());
chain.doFilter(request, response); // 传递给下一个过滤器
}
}
4.3.2 Tomcat的Pipeline-Valve机制
Tomcat容器(Engine/Host/Context/Wrapper)通过Pipeline-Valve实现责任链:
- Pipeline:维护Valve链的容器
- Valve:具体处理节点,如
StandardEngineValve、StandardHostValve
层级调用流程:
EngineValve → HostValve → ContextValve → WrapperValve → Servlet
核心接口:
public interface Valve {
Valve getNext();
void setNext(Valve valve);
void invoke(Request request, Response response); // 处理请求
}
4.4 优缺点分析
| 优点 | 缺点 |
|---|---|
| 解耦请求发送者与处理者 | 链过长可能导致性能损耗 |
| 动态组合处理逻辑(增减处理者) | 请求可能未被处理而到达链尾 |
| 符合单一职责原则 | 调试复杂(需追踪整条链) |
五、总结:设计模式在框架中的应用全景
| 设计模式 | 核心思想 | 典型框架应用场景 |
|---|---|---|
| 单例模式 | 唯一实例+全局访问 | Spring Bean默认单例(三级缓存解决循环依赖)、数据库连接池 |
| 工厂模式 | 封装对象创建逻辑 | Spring BeanFactory/ApplicationContext、MyBatis SqlSessionFactory |
| 装饰器模式 | 动态扩展功能 | MyBatis缓存(LruCache/LoggingCache)、JDK IO流(BufferedReader) |
| 适配器模式 | 接口转换兼容 | Spring MVC HandlerAdapter、JDBC驱动适配 |
| 策略模式 | 算法族封装与互换 | Spring Resource资源访问、支付方式选择 |
| 代理模式 | 控制对象访问 | Spring AOP(JDK/CGLIB代理)、事务管理 |
| 观察者模式 | 事件发布-订阅机制 | Spring事件机制(ApplicationEvent/Listener)、GUI界面事件 |
设计模式的价值不仅在于“代码模板”,更在于其背后的设计原则(如开闭原则、单一职责原则)。在实际开发中,应结合业务场景灵活选择,避免过度设计。通过学习Spring、MyBatis等框架对设计模式的经典应用,我们能更深刻地理解“为何用”而非“如何用”,真正提升架构设计能力。
8万+

被折叠的 条评论
为什么被折叠?



