设计模式组合使用详解
目录
模式组合概述
设计模式组合的意义
设计模式组合是指在实际开发中,将多个设计模式结合使用来解决复杂问题。单一模式往往无法满足复杂业务需求,通过模式组合可以实现更灵活、更强大的解决方案。
组合原则
- 互补性:选择相互补充的模式
- 层次性:不同层次使用不同模式
- 职责分离:每个模式负责特定职责
- 可维护性:组合后仍保持代码可维护性
常见模式组合场景
1. 单例 + 工厂模式
应用场景
- 数据库连接池管理
- 线程池管理
- 缓存管理器
实现示例
java
// 单例 + 工厂模式组合
public class DatabaseConnectionManager {
private static volatile DatabaseConnectionManager instance;
private final Map<String, ConnectionFactory> factories = new HashMap<>();
private DatabaseConnectionManager() {
// 注册不同类型的连接工厂
factories.put("mysql", new MySQLConnectionFactory());
factories.put("oracle", new OracleConnectionFactory());
factories.put("postgresql", new PostgreSQLConnectionFactory());
}
public static DatabaseConnectionManager getInstance() {
if (instance == null) {
synchronized (DatabaseConnectionManager.class) {
if (instance == null) {
instance = new DatabaseConnectionManager();
}
}
}
return instance;
}
public Connection createConnection(String dbType, String url, String username, String password) {
ConnectionFactory factory = factories.get(dbType);
if (factory == null) {
throw new IllegalArgumentException("不支持的数据库类型: " + dbType);
}
return factory.createConnection(url, username, password);
}
}
2. 观察者 + 策略模式
应用场景
- 事件处理系统
- 消息通知系统
- 状态变化处理
实现示例
java
// 观察者 + 策略模式组合
public class EventProcessor {
private final List<EventHandler> handlers = new ArrayList<>();
private EventStrategy strategy;
public void addHandler(EventHandler handler) {
handlers.add(handler);
}
public void setStrategy(EventStrategy strategy) {
this.strategy = strategy;
}
public void processEvent(Event event) {
// 使用策略模式选择处理方式
EventContext context = strategy.createContext(event);
// 使用观察者模式通知所有处理器
for (EventHandler handler : handlers) {
if (handler.canHandle(event)) {
handler.handle(event, context);
}
}
}
}
// 事件处理策略
public interface EventStrategy {
EventContext createContext(Event event);
}
// 同步处理策略
public class SyncEventStrategy implements EventStrategy {
@Override
public EventContext createContext(Event event) {
return new SyncEventContext(event);
}
}
// 异步处理策略
public class AsyncEventStrategy implements EventStrategy {
@Override
public EventContext createContext(Event event) {
return new AsyncEventContext(event);
}
}
3. 装饰器 + 适配器模式
应用场景
- 第三方库集成
- 功能增强
- 接口兼容
实现示例
java
// 装饰器 + 适配器模式组合
public class EnhancedDataProcessor implements DataProcessor {
private final DataProcessor target;
private final DataProcessorAdapter adapter;
public EnhancedDataProcessor(DataProcessor target, DataProcessorAdapter adapter) {
this.target = target;
this.adapter = adapter;
}
@Override
public void process(Data data) {
// 适配器模式:转换数据格式
Data adaptedData = adapter.adapt(data);
// 装饰器模式:增强功能
preProcess(adaptedData);
target.process(adaptedData);
postProcess(adaptedData);
}
private void preProcess(Data data) {
// 预处理逻辑
System.out.println("数据预处理");
}
private void postProcess(Data data) {
// 后处理逻辑
System.out.println("数据后处理");
}
}
// 数据处理器适配器
public interface DataProcessorAdapter {
Data adapt(Data data);
}
// JSON数据适配器
public class JsonDataAdapter implements DataProcessorAdapter {
@Override
public Data adapt(Data data) {
// 将数据转换为JSON格式
return new JsonData(data);
}
}
4. 建造者 + 模板方法模式
应用场景
- 复杂对象构建
- 流程控制
- 配置管理
实现示例
java
// 建造者 + 模板方法模式组合
public abstract class ConfigBuilder {
protected Config config = new Config();
// 模板方法:定义构建流程
public final Config build() {
validateInput();
buildBasicConfig();
buildAdvancedConfig();
validateConfig();
return config;
}
// 抽象方法:子类实现具体逻辑
protected abstract void buildBasicConfig();
protected abstract void buildAdvancedConfig();
// 钩子方法:子类可以重写
protected void validateInput() {
// 默认验证逻辑
}
protected void validateConfig() {
// 默认验证逻辑
}
}
// 数据库配置构建器
public class DatabaseConfigBuilder extends ConfigBuilder {
@Override
protected void buildBasicConfig() {
config.setHost("localhost");
config.setPort(3306);
}
@Override
protected void buildAdvancedConfig() {
config.setConnectionPoolSize(10);
config.setTimeout(30000);
}
}
// 缓存配置构建器
public class CacheConfigBuilder extends ConfigBuilder {
@Override
protected void buildBasicConfig() {
config.setCacheType("redis");
config.setMaxSize(1000);
}
@Override
protected void buildAdvancedConfig() {
config.setExpireTime(3600);
config.setEvictionPolicy("LRU");
}
}
5. 责任链 + 命令模式
应用场景
- 请求处理链
- 权限验证
- 业务流程控制
实现示例
java
// 责任链 + 命令模式组合
public abstract class RequestHandler {
protected RequestHandler nextHandler;
public void setNext(RequestHandler handler) {
this.nextHandler = handler;
}
public void handle(Request request) {
if (canHandle(request)) {
processRequest(request);
} else if (nextHandler != null) {
nextHandler.handle(request);
}
}
protected abstract boolean canHandle(Request request);
protected abstract void processRequest(Request request);
}
// 认证处理器
public class AuthenticationHandler extends RequestHandler {
@Override
protected boolean canHandle(Request request) {
return request.getType() == RequestType.AUTHENTICATION;
}
@Override
protected void processRequest(Request request) {
// 执行认证命令
Command authCommand = new AuthenticationCommand(request);
authCommand.execute();
}
}
// 授权处理器
public class AuthorizationHandler extends RequestHandler {
@Override
protected boolean canHandle(Request request) {
return request.getType() == RequestType.AUTHORIZATION;
}
@Override
protected void processRequest(Request request) {
// 执行授权命令
Command authzCommand = new AuthorizationCommand(request);
authzCommand.execute();
}
}
// 命令接口
public interface Command {
void execute();
void undo();
}
// 认证命令
public class AuthenticationCommand implements Command {
private final Request request;
public AuthenticationCommand(Request request) {
this.request = request;
}
@Override
public void execute() {
// 执行认证逻辑
System.out.println("执行认证: " + request.getId());
}
@Override
public void undo() {
// 撤销认证逻辑
System.out.println("撤销认证: " + request.getId());
}
}
Spring源码中的组合应用
1. 单例 + 工厂 + 策略模式
核心类:ApplicationContext
java
public interface ApplicationContext extends BeanFactory, ResourceLoader, ApplicationEventPublisher {
// 单例模式:管理Bean实例
Object getBean(String name) throws BeansException;
// 工厂模式:创建Bean实例
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 策略模式:不同的Bean创建策略
<T> T getBean(Class<T> requiredType) throws BeansException;
}
// 实现类:DefaultListableBeanFactory
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
// 单例Bean缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// Bean创建策略
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
@Override
public Object getBean(String name) throws BeansException {
// 单例模式:从缓存获取
Object bean = this.singletonObjects.get(name);
if (bean != null) {
return bean;
}
// 工厂模式:创建Bean实例
return createBean(name, getBeanDefinition(name));
}
protected Object createBean(String beanName, BeanDefinition beanDefinition) {
// 策略模式:根据Bean类型选择创建策略
if (beanDefinition.isSingleton()) {
return createSingleton(beanName, beanDefinition);
} else if (beanDefinition.isPrototype()) {
return createPrototype(beanName, beanDefinition);
} else {
return createBean(beanName, beanDefinition);
}
}
}
2. 观察者 + 模板方法 + 策略模式
核心类:ApplicationEventPublisher
java
public interface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event);
void publishEvent(Object event);
}
// 实现类:SimpleApplicationEventMulticaster
public class SimpleApplicationEventMulticaster implements ApplicationEventMulticaster {
// 观察者模式:事件监听器列表
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
// 策略模式:不同的监听器调用策略
private Executor taskExecutor;
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
// 模板方法:定义事件发布流程
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 策略模式:选择监听器调用策略
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
invokeListener(listener, event);
}
}
// 模板方法:调用监听器
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
if (taskExecutor != null) {
// 异步策略
taskExecutor.execute(() -> doInvokeListener(listener, event));
} else {
// 同步策略
doInvokeListener(listener, event);
}
}
// 具体实现:子类可以重写
protected void doInvokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
} catch (ClassCastException ex) {
// 处理类型转换异常
}
}
}
3. 装饰器 + 适配器 + 代理模式
核心类:AopProxy
java
public interface AopProxy {
Object getProxy();
Object getProxy(ClassLoader classLoader);
}
// 装饰器模式:增强目标对象
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
private final AdvisedSupport advised;
public JdkDynamicAopProxy(AdvisedSupport config) {
this.advised = config;
}
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(ClassLoader classLoader) {
// 适配器模式:适配目标接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
// 代理模式:创建代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 装饰器模式:增强方法调用
Object retVal;
// 前置增强
if (this.advised.getExposeProxy()) {
AopContext.setCurrentProxy(proxy);
}
try {
// 执行目标方法
retVal = method.invoke(this.advised.getTarget(), args);
} catch (InvocationTargetException ex) {
// 异常处理
throw ex.getTargetException();
} finally {
// 后置增强
if (this.advised.getExposeProxy()) {
AopContext.setCurrentProxy(null);
}
}
return retVal;
}
}
4. 建造者 + 模板方法 + 策略模式
核心类:SpringApplicationBuilder
java
public class SpringApplicationBuilder {
private final SpringApplication application;
private final ConfigurableEnvironment environment;
// 建造者模式:构建Spring应用
public SpringApplicationBuilder(Class<?>... sources) {
this.application = new SpringApplication(sources);
this.environment = new StandardEnvironment();
}
// 模板方法:定义构建流程
public SpringApplication build() {
// 1. 配置环境
configureEnvironment();
// 2. 配置应用
configureApplication();
// 3. 配置监听器
configureListeners();
return application;
}
// 策略模式:不同的配置策略
public SpringApplicationBuilder profiles(String... profiles) {
application.setAdditionalProfiles(profiles);
return this;
}
public SpringApplicationBuilder web(WebApplicationType webApplicationType) {
application.setWebApplicationType(webApplicationType);
return this;
}
public SpringApplicationBuilder bannerMode(Banner.Mode bannerMode) {
application.setBannerMode(bannerMode);
return this;
}
// 钩子方法:子类可以重写
protected void configureEnvironment() {
// 默认环境配置
}
protected void configureApplication() {
// 默认应用配置
}
protected void configureListeners() {
// 默认监听器配置
}
}
组合使用重难点分析
1. 模式冲突问题
问题描述
不同模式之间可能存在冲突,导致设计复杂化。
解决方案
java
// 问题:单例模式与原型模式冲突
public class BeanFactory {
// 单例模式:全局唯一实例
private static volatile BeanFactory instance;
// 原型模式:每次创建新实例
public Object createPrototype(String beanName) {
// 冲突:单例工厂如何创建原型Bean?
return new Object();
}
}
// 解决方案:使用策略模式分离职责
public class BeanFactory {
private static volatile BeanFactory instance;
private final Map<String, BeanCreationStrategy> strategies = new HashMap<>();
public BeanFactory() {
strategies.put("singleton", new SingletonBeanStrategy());
strategies.put("prototype", new PrototypeBeanStrategy());
}
public Object createBean(String beanName, String scope) {
BeanCreationStrategy strategy = strategies.get(scope);
if (strategy == null) {
throw new IllegalArgumentException("不支持的Bean作用域: " + scope);
}
return strategy.createBean(beanName);
}
}
2. 职责边界模糊
问题描述
多个模式组合时,职责边界可能变得模糊。
解决方案
java
// 问题:装饰器模式与适配器模式职责重叠
public class DataProcessor {
// 装饰器:增强功能
public void process(Data data) {
preProcess(data);
doProcess(data);
postProcess(data);
}
// 适配器:转换格式
public void adapt(Data data) {
// 职责重叠
}
}
// 解决方案:明确职责边界
public class DataProcessor {
private final DataAdapter adapter;
private final DataEnhancer enhancer;
public void process(Data data) {
// 适配器:负责格式转换
Data adaptedData = adapter.adapt(data);
// 装饰器:负责功能增强
enhancer.enhance(adaptedData);
// 核心处理
doProcess(adaptedData);
}
}
3. 性能问题
问题描述
模式组合可能导致性能问题。
解决方案
java
// 问题:多层装饰器导致性能问题
public class DataProcessor {
private final List<DataDecorator> decorators = new ArrayList<>();
public void process(Data data) {
// 多层装饰器调用
for (DataDecorator decorator : decorators) {
data = decorator.decorate(data);
}
}
}
// 解决方案:使用缓存和优化
public class OptimizedDataProcessor {
private final Map<String, DataProcessor> processorCache = new ConcurrentHashMap<>();
public void process(Data data) {
String key = generateKey(data);
DataProcessor processor = processorCache.computeIfAbsent(key, this::createProcessor);
processor.process(data);
}
private DataProcessor createProcessor(String key) {
// 根据key创建优化的处理器
return new OptimizedProcessor();
}
}
4. 测试复杂性
问题描述
模式组合增加了测试的复杂性。
解决方案
java
// 问题:复杂模式组合难以测试
public class ComplexService {
private final List<Handler> handlers;
private final Strategy strategy;
private final Factory factory;
public ComplexService(List<Handler> handlers, Strategy strategy, Factory factory) {
this.handlers = handlers;
this.strategy = strategy;
this.factory = factory;
}
public void process(Request request) {
// 复杂的处理逻辑
}
}
// 解决方案:使用测试替身和依赖注入
public class ComplexServiceTest {
@Test
public void testProcess() {
// 使用Mock对象
List<Handler> mockHandlers = Arrays.asList(
mock(Handler.class),
mock(Handler.class)
);
Strategy mockStrategy = mock(Strategy.class);
Factory mockFactory = mock(Factory.class);
ComplexService service = new ComplexService(mockHandlers, mockStrategy, mockFactory);
// 测试逻辑
service.process(new Request());
// 验证调用
verify(mockStrategy).execute(any());
}
}
面试高频点
1. 基本概念类
Q: 什么是设计模式组合?为什么要组合使用?
A: 设计模式组合是指在实际开发中,将多个设计模式结合使用来解决复杂问题。单一模式往往无法满足复杂业务需求,通过模式组合可以实现更灵活、更强大的解决方案。
组合的原因:
- 单一模式功能有限
- 复杂业务需要多种模式协作
- 提高代码的灵活性和可维护性
- 更好地符合开闭原则
Q: 设计模式组合的原则是什么?
A:
- 互补性:选择相互补充的模式
- 层次性:不同层次使用不同模式
- 职责分离:每个模式负责特定职责
- 可维护性:组合后仍保持代码可维护性
2. 实际应用类
Q: 在Spring框架中,哪些地方使用了模式组合?
A:
- ApplicationContext:单例 + 工厂 + 策略模式
- AOP:装饰器 + 适配器 + 代理模式
- 事件处理:观察者 + 模板方法 + 策略模式
- Bean创建:建造者 + 模板方法 + 策略模式
Q: 如何设计一个支持多种数据库的连接池?
A:
java
// 单例 + 工厂 + 策略模式组合
public class DatabaseConnectionPool {
private static volatile DatabaseConnectionPool instance;
private final Map<String, ConnectionFactory> factories = new HashMap<>();
private DatabaseConnectionPool() {
factories.put("mysql", new MySQLConnectionFactory());
factories.put("oracle", new OracleConnectionFactory());
}
public static DatabaseConnectionPool getInstance() {
if (instance == null) {
synchronized (DatabaseConnectionPool.class) {
if (instance == null) {
instance = new DatabaseConnectionPool();
}
}
}
return instance;
}
public Connection getConnection(String dbType, String url, String username, String password) {
ConnectionFactory factory = factories.get(dbType);
if (factory == null) {
throw new IllegalArgumentException("不支持的数据库类型: " + dbType);
}
return factory.createConnection(url, username, password);
}
}
3. 设计权衡类
Q: 模式组合可能遇到哪些问题?
A:
- 模式冲突:不同模式之间可能存在冲突
- 职责边界模糊:多个模式组合时职责边界可能变得模糊
- 性能问题:模式组合可能导致性能问题
- 测试复杂性:模式组合增加了测试的复杂性
Q: 如何解决模式组合中的冲突问题?
A:
java
// 使用策略模式分离冲突的职责
public class BeanFactory {
private final Map<String, BeanCreationStrategy> strategies = new HashMap<>();
public BeanFactory() {
strategies.put("singleton", new SingletonBeanStrategy());
strategies.put("prototype", new PrototypeBeanStrategy());
}
public Object createBean(String beanName, String scope) {
BeanCreationStrategy strategy = strategies.get(scope);
if (strategy == null) {
throw new IllegalArgumentException("不支持的Bean作用域: " + scope);
}
return strategy.createBean(beanName);
}
}
4. 性能优化类
Q: 如何优化模式组合的性能?
A:
- 使用缓存:避免重复创建对象
- 对象池:减少对象创建开销
- 延迟加载:按需创建对象
- 异步处理:提高并发性能
java
// 使用缓存优化性能
public class OptimizedService {
private final Map<String, Object> cache = new ConcurrentHashMap<>();
public Object process(String key, Object data) {
return cache.computeIfAbsent(key, k -> doProcess(data));
}
private Object doProcess(Object data) {
// 复杂的处理逻辑
return new Object();
}
}
5. 测试相关类
Q: 如何测试复杂的模式组合?
A:
- 使用Mock对象:模拟依赖
- 依赖注入:便于测试
- 单元测试:测试单个模式
- 集成测试:测试模式组合
java
// 使用Mock对象测试
public class ComplexServiceTest {
@Test
public void testProcess() {
// 创建Mock对象
Handler mockHandler = mock(Handler.class);
Strategy mockStrategy = mock(Strategy.class);
// 创建测试对象
ComplexService service = new ComplexService(mockHandler, mockStrategy);
// 执行测试
service.process(new Request());
// 验证调用
verify(mockHandler).handle(any());
verify(mockStrategy).execute(any());
}
}
相关总结
模式组合最佳实践
1. 选择合适的模式组合
- 功能互补:选择功能相互补充的模式
- 层次分离:在不同层次使用不同模式
- 职责明确:每个模式有明确的职责
- 易于维护:组合后代码仍然易于维护
2. 避免过度设计
- 简单优先:能用简单方案解决的不要用复杂组合
- 按需组合:根据实际需求选择合适的模式组合
- 渐进式设计:从简单开始,逐步增加复杂性
3. 性能考虑
- 缓存机制:使用缓存避免重复计算
- 对象池:使用对象池减少对象创建开销
- 异步处理:使用异步处理提高并发性能
- 资源管理:及时释放资源,避免内存泄漏
4. 测试策略
- 单元测试:为每个模式编写单元测试
- 集成测试:测试模式组合的整体功能
- Mock对象:使用Mock对象模拟依赖
- 测试覆盖:确保测试覆盖所有场景
常见模式组合总结
1. 创建型模式组合
- 单例 + 工厂:管理全局唯一的工厂实例
- 建造者 + 模板方法:定义复杂对象的构建流程
- 原型 + 工厂:快速创建相似对象
2. 结构型模式组合
- 装饰器 + 适配器:增强和适配第三方库
- 代理 + 装饰器:代理目标对象并增强功能
- 外观 + 适配器:简化复杂系统的接口
3. 行为型模式组合
- 观察者 + 策略:根据策略选择不同的观察者
- 命令 + 责任链:将命令作为责任链中的处理单元
- 状态 + 策略:根据状态选择不同的策略
设计原则总结
1. 开闭原则
- 对扩展开放,对修改关闭
- 通过模式组合实现功能的扩展
2. 单一职责原则
- 每个模式负责特定的职责
- 通过组合实现复杂功能
3. 依赖倒置原则
- 依赖抽象而不是具体实现
- 通过接口实现模式组合
4. 接口隔离原则
- 客户端不应该依赖它不需要的接口
- 通过接口分离实现模式组合
总结
设计模式组合是解决复杂问题的重要手段,通过合理组合多个模式,可以实现更灵活、更强大的解决方案。在实际应用中,需要根据具体需求选择合适的模式组合,并注意避免过度设计和性能问题。
关键要点:
- 合理组合:选择功能互补的模式进行组合
- 职责分离:每个模式负责特定的职责
- 性能优化:使用缓存、对象池等技术优化性能
- 测试策略:编写全面的测试确保质量
- 避免过度设计:根据实际需求选择合适的组合
适用场景:
- 复杂业务逻辑
- 第三方库集成
- 系统架构设计
- 框架开发
注意事项:
- 避免模式冲突
- 保持代码可维护性
- 注意性能影响
- 编写充分测试