当前位置: 首页 > news >正文

设计模式-策略模式深度分析

策略模式深度分析

目录

  1. 策略模式概述
  2. 实际应用场景
  3. 重难点分析
  4. Spring源码中的策略模式应用
  5. 最佳实践与设计建议
  6. 总结

策略模式概述

策略模式(Strategy Pattern)是一种行为型设计模式,属于GoF 23种设计模式之一。它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。

核心组件

  • Strategy(策略接口):定义所有具体策略的公共接口
  • ConcreteStrategy(具体策略):实现策略接口的具体算法
  • Context(上下文):持有一个策略对象的引用,并调用策略对象的方法

设计原则

  • 开闭原则:对扩展开放,对修改关闭
  • 单一职责原则:每个策略类只负责一种算法
  • 依赖倒置原则:依赖抽象而不是具体实现

实际应用场景

1. 支付系统

// 支付策略接口
public interface PaymentStrategy {void pay(BigDecimal amount);
}// 支付宝支付策略
public class AlipayStrategy implements PaymentStrategy {@Overridepublic void pay(BigDecimal amount) {System.out.println("使用支付宝支付:" + amount);}
}// 微信支付策略
public class WechatPayStrategy implements PaymentStrategy {@Overridepublic void pay(BigDecimal amount) {System.out.println("使用微信支付:" + amount);}
}// 支付上下文
public class PaymentContext {private PaymentStrategy strategy;public void setStrategy(PaymentStrategy strategy) {this.strategy = strategy;}public void executePayment(BigDecimal amount) {strategy.pay(amount);}
}

2. 数据压缩系统

// 压缩策略接口
public interface CompressionStrategy {byte[] compress(byte[] data);byte[] decompress(byte[] compressedData);
}// ZIP压缩策略
public class ZipCompressionStrategy implements CompressionStrategy {@Overridepublic byte[] compress(byte[] data) {// ZIP压缩实现return zipCompress(data);}@Overridepublic byte[] decompress(byte[] compressedData) {// ZIP解压实现return zipDecompress(compressedData);}
}// GZIP压缩策略
public class GzipCompressionStrategy implements CompressionStrategy {@Overridepublic byte[] compress(byte[] data) {// GZIP压缩实现return gzipCompress(data);}@Overridepublic byte[] decompress(byte[] compressedData) {// GZIP解压实现return gzipDecompress(compressedData);}
}

3. 日志记录系统

// 日志策略接口
public interface LoggingStrategy {void log(String message, LogLevel level);
}// 文件日志策略
public class FileLoggingStrategy implements LoggingStrategy {@Overridepublic void log(String message, LogLevel level) {// 写入文件writeToFile(message, level);}
}// 数据库日志策略
public class DatabaseLoggingStrategy implements LoggingStrategy {@Overridepublic void log(String message, LogLevel level) {// 写入数据库writeToDatabase(message, level);}
}// 控制台日志策略
public class ConsoleLoggingStrategy implements LoggingStrategy {@Overridepublic void log(String message, LogLevel level) {// 输出到控制台System.out.println(level + ": " + message);}
}

4. 排序算法选择

// 排序策略接口
public interface SortStrategy {void sort(int[] array);
}// 快速排序策略
public class QuickSortStrategy implements SortStrategy {@Overridepublic void sort(int[] array) {// 快速排序实现quickSort(array, 0, array.length - 1);}
}// 归并排序策略
public class MergeSortStrategy implements SortStrategy {@Overridepublic void sort(int[] array) {// 归并排序实现mergeSort(array, 0, array.length - 1);}
}// 堆排序策略
public class HeapSortStrategy implements SortStrategy {@Overridepublic void sort(int[] array) {// 堆排序实现heapSort(array);}
}

5. 数据验证系统

// 验证策略接口
public interface ValidationStrategy {boolean validate(String data);
}// 邮箱验证策略
public class EmailValidationStrategy implements ValidationStrategy {@Overridepublic boolean validate(String data) {return data.matches("^[A-Za-z0-9+_.-]+@(.+)$");}
}// 手机号验证策略
public class PhoneValidationStrategy implements ValidationStrategy {@Overridepublic boolean validate(String data) {return data.matches("^1[3-9]\\d{9}$");}
}// 身份证验证策略
public class IdCardValidationStrategy implements ValidationStrategy {@Overridepublic boolean validate(String data) {return data.matches("^\\d{17}[\\dXx]$");}
}

重难点分析

1. 策略选择机制设计

难点
  • 如何根据运行时条件动态选择合适的策略
  • 避免硬编码策略选择逻辑
  • 支持策略的优先级和回退机制
解决方案
// 策略选择器接口
public interface StrategySelector<T> {T selectStrategy(String key, Map<String, T> strategies);
}// 基于配置的策略选择器
public class ConfigBasedStrategySelector<T> implements StrategySelector<T> {private final String defaultStrategy;public ConfigBasedStrategySelector(String defaultStrategy) {this.defaultStrategy = defaultStrategy;}@Overridepublic T selectStrategy(String key, Map<String, T> strategies) {String strategyKey = getStrategyKeyFromConfig(key);T strategy = strategies.get(strategyKey);if (strategy == null) {strategy = strategies.get(defaultStrategy);}return strategy;}
}// 基于规则的策略选择器
public class RuleBasedStrategySelector<T> implements StrategySelector<T> {private final List<StrategyRule<T>> rules;@Overridepublic T selectStrategy(String key, Map<String, T> strategies) {for (StrategyRule<T> rule : rules) {if (rule.matches(key)) {return rule.getStrategy(strategies);}}return strategies.values().iterator().next();}
}

2. 策略生命周期管理

难点
  • 策略对象的创建和销毁
  • 策略的缓存和复用
  • 策略的线程安全性
解决方案
// 策略工厂接口
public interface StrategyFactory<T> {T createStrategy(String strategyType);void destroyStrategy(T strategy);
}// 单例策略工厂
public class SingletonStrategyFactory<T> implements StrategyFactory<T> {private final Map<String, T> strategyCache = new ConcurrentHashMap<>();private final Function<String, T> strategyCreator;public SingletonStrategyFactory(Function<String, T> strategyCreator) {this.strategyCreator = strategyCreator;}@Overridepublic T createStrategy(String strategyType) {return strategyCache.computeIfAbsent(strategyType, strategyCreator);}@Overridepublic void destroyStrategy(T strategy) {// 清理资源strategyCache.values().removeIf(s -> s == strategy);}
}

3. 策略参数传递

难点
  • 不同策略可能需要不同的参数
  • 参数类型安全
  • 参数验证
解决方案
// 策略上下文
public class StrategyContext {private final Map<String, Object> parameters = new HashMap<>();public <T> T getParameter(String key, Class<T> type) {Object value = parameters.get(key);if (value != null && type.isAssignableFrom(value.getClass())) {return type.cast(value);}return null;}public void setParameter(String key, Object value) {parameters.put(key, value);}
}// 增强的策略接口
public interface EnhancedStrategy {void execute(StrategyContext context);
}

4. 策略组合和链式调用

难点
  • 多个策略的组合使用
  • 策略的执行顺序
  • 策略间的数据传递
解决方案
// 策略链
public class StrategyChain<T> {private final List<Strategy<T>> strategies = new ArrayList<>();public StrategyChain<T> addStrategy(Strategy<T> strategy) {strategies.add(strategy);return this;}public T execute(T input) {T result = input;for (Strategy<T> strategy : strategies) {result = strategy.execute(result);}return result;}
}// 组合策略
public class CompositeStrategy<T> implements Strategy<T> {private final List<Strategy<T>> strategies;public CompositeStrategy(List<Strategy<T>> strategies) {this.strategies = strategies;}@Overridepublic T execute(T input) {T result = input;for (Strategy<T> strategy : strategies) {result = strategy.execute(result);}return result;}
}

Spring源码中的策略模式应用

1. ResourceLoader策略模式

Spring使用策略模式来处理不同类型的资源加载:

// ResourceLoader接口
public interface ResourceLoader {Resource getResource(String location);ClassLoader getClassLoader();
}// 具体实现类
public class DefaultResourceLoader implements ResourceLoader {@Overridepublic Resource getResource(String location) {if (location.startsWith("/")) {return getResourceByPath(location);} else if (location.startsWith(CLASSPATH_URL_PREFIX)) {return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());} else if (location.startsWith("file:")) {return new FileUrlResource(location);} else if (location.startsWith("http:")) {return new UrlResource(location);} else {return getResourceByPath(location);}}
}

2. BeanDefinitionReader策略模式

Spring使用策略模式来支持不同的Bean定义读取方式:

// BeanDefinitionReader接口
public interface BeanDefinitionReader {BeanDefinitionRegistry getRegistry();ResourceLoader getResourceLoader();ClassLoader getBeanClassLoader();BeanNameGenerator getBeanNameGenerator();int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}// XML Bean定义读取器
public class XmlBeanDefinitionReader implements BeanDefinitionReader {// XML解析实现
}// Properties Bean定义读取器
public class PropertiesBeanDefinitionReader implements BeanDefinitionReader {// Properties解析实现
}// Groovy Bean定义读取器
public class GroovyBeanDefinitionReader implements BeanDefinitionReader {// Groovy解析实现
}

3. ViewResolver策略模式

Spring MVC使用策略模式来支持不同的视图解析方式:

// ViewResolver接口
public interface ViewResolver {View resolveViewName(String viewName, Locale locale) throws Exception;
}// 内部资源视图解析器
public class InternalResourceViewResolver extends UrlBasedViewResolver {@Overrideprotected View buildView(String viewName) throws Exception {InternalResourceView view = (InternalResourceView) super.buildView(viewName);if (this.alwaysInclude != null) {view.setAlwaysInclude(this.alwaysInclude);}return view;}
}// Thymeleaf视图解析器
public class ThymeleafViewResolver extends AbstractCachingViewResolver {@Overrideprotected View createView(String viewName, Locale locale) throws Exception {if (!canHandle(viewName, locale)) {return null;}return super.createView(viewName, locale);}
}

4. PlatformTransactionManager策略模式

Spring使用策略模式来支持不同的事务管理方式:

// 事务管理器接口
public interface PlatformTransactionManager {TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;void commit(TransactionStatus status) throws TransactionException;void rollback(TransactionStatus status) throws TransactionException;
}// JDBC事务管理器
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager {@Overrideprotected Object doGetTransaction() {DataSourceTransactionObject txObject = new DataSourceTransactionObject();txObject.setSavepointAllowed(isNestedTransactionAllowed());ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());txObject.setConnectionHolder(conHolder, false);return txObject;}
}// JTA事务管理器
public class JtaTransactionManager extends AbstractPlatformTransactionManager {@Overrideprotected Object doGetTransaction() {JtaTransactionObject txObject = new JtaTransactionObject();txObject.setUserTransaction(this.userTransaction);txObject.setTransactionManager(this.transactionManager);return txObject;}
}

5. HandlerMapping策略模式

Spring MVC使用策略模式来支持不同的请求映射方式:

// 处理器映射接口
public interface HandlerMapping {HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}// 注解处理器映射
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping {@Overrideprotected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);}
}// 简单URL处理器映射
public class SimpleUrlHandlerMapping extends AbstractUrlHandlerMapping {@Overrideprotected Object getHandlerInternal(HttpServletRequest request) throws Exception {String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);Object handler = lookupHandler(lookupPath, request);if (handler == null) {Object rawHandler = null;if (lookupPath.equals("/")) {rawHandler = getRootHandler();}if (rawHandler == null) {rawHandler = getDefaultHandler();}if (rawHandler != null) {handler = (rawHandler instanceof String ? obtainApplicationContext().getBean((String) rawHandler) : rawHandler);}}return handler;}
}

6. InstantiationStrategy策略模式

Spring使用策略模式来支持不同的Bean实例化方式:

// 实例化策略接口
public interface InstantiationStrategy {Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) throws BeansException;Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Constructor<?> ctor, Object... args) throws BeansException;Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Object factoryBean, Method factoryMethod, Object... args) throws BeansException;
}// 简单实例化策略
public class SimpleInstantiationStrategy implements InstantiationStrategy {@Overridepublic Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {if (bd.getMethodOverrides().isEmpty()) {Constructor<?> constructorToUse;synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");}try {if (System.getSecurityManager() != null) {constructorToUse = AccessController.doPrivileged((PrivilegedAction<Constructor<?>>) clazz::getDeclaredConstructor);} else {constructorToUse = clazz.getDeclaredConstructor();}bd.resolvedConstructorOrFactoryMethod = constructorToUse;} catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}return BeanUtils.instantiateClass(constructorToUse);} else {return instantiateWithMethodInjection(bd, beanName, owner);}}
}// CGLIB实例化策略
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {@Overridepublic Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {if (!bd.hasMethodOverrides()) {Constructor<?> constructorToUse;synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");}try {if (System.getSecurityManager() != null) {constructorToUse = AccessController.doPrivileged((PrivilegedAction<Constructor<?>>) clazz::getDeclaredConstructor);} else {constructorToUse = clazz.getDeclaredConstructor();}bd.resolvedConstructorOrFactoryMethod = constructorToUse;} catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}return BeanUtils.instantiateClass(constructorToUse);} else {return instantiateWithMethodInjection(bd, beanName, owner);}}
}

最佳实践与设计建议

1. 策略接口设计原则

// 好的策略接口设计
public interface PaymentStrategy {// 单一职责:只负责支付PaymentResult pay(PaymentRequest request);// 支持策略标识String getStrategyName();// 支持策略验证boolean supports(PaymentRequest request);
}// 避免的设计
public interface BadPaymentStrategy {// 职责过多:支付、验证、通知等PaymentResult pay(PaymentRequest request);boolean validate(PaymentRequest request);void sendNotification(PaymentResult result);void logPayment(PaymentResult result);
}

2. 策略选择机制

// 基于注解的策略选择
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface StrategyType {String value();
}@StrategyType("alipay")
public class AlipayStrategy implements PaymentStrategy {// 实现
}// 策略注册器
@Component
public class StrategyRegistry {private final Map<String, PaymentStrategy> strategies = new HashMap<>();@PostConstructpublic void initStrategies() {// 扫描并注册所有策略ApplicationContext context = getApplicationContext();Map<String, PaymentStrategy> strategyBeans = context.getBeansOfType(PaymentStrategy.class);for (PaymentStrategy strategy : strategyBeans.values()) {StrategyType annotation = strategy.getClass().getAnnotation(StrategyType.class);if (annotation != null) {strategies.put(annotation.value(), strategy);}}}public PaymentStrategy getStrategy(String type) {return strategies.get(type);}
}

3. 策略配置管理

// 策略配置
@Configuration
public class StrategyConfiguration {@Bean@ConditionalOnProperty(name = "payment.alipay.enabled", havingValue = "true")public PaymentStrategy alipayStrategy() {return new AlipayStrategy();}@Bean@ConditionalOnProperty(name = "payment.wechat.enabled", havingValue = "true")public PaymentStrategy wechatPayStrategy() {return new WechatPayStrategy();}@Beanpublic StrategySelector<PaymentStrategy> paymentStrategySelector() {return new ConfigBasedStrategySelector<>("alipay");}
}

4. 策略性能优化

// 策略缓存
@Component
public class CachedStrategyRegistry {private final Map<String, PaymentStrategy> strategyCache = new ConcurrentHashMap<>();private final StrategyFactory<PaymentStrategy> strategyFactory;public PaymentStrategy getStrategy(String type) {return strategyCache.computeIfAbsent(type, strategyFactory::createStrategy);}@PreDestroypublic void clearCache() {strategyCache.clear();}
}// 策略预热
@Component
public class StrategyWarmupService {@EventListenerpublic void onApplicationReady(ApplicationReadyEvent event) {// 预热常用策略List<String> commonStrategies = Arrays.asList("alipay", "wechat");for (String strategyType : commonStrategies) {strategyRegistry.getStrategy(strategyType);}}
}

5. 策略监控和日志

// 策略执行监控
@Component
public class StrategyExecutionMonitor {private final MeterRegistry meterRegistry;public <T> T executeWithMonitoring(String strategyName, Supplier<T> strategyExecution) {Timer.Sample sample = Timer.start(meterRegistry);try {T result = strategyExecution.get();sample.stop(Timer.builder("strategy.execution.time").tag("strategy", strategyName).tag("status", "success").register(meterRegistry));return result;} catch (Exception e) {sample.stop(Timer.builder("strategy.execution.time").tag("strategy", strategyName).tag("status", "error").register(meterRegistry));throw e;}}
}// 策略执行日志
@Aspect
@Component
public class StrategyExecutionAspect {private static final Logger logger = LoggerFactory.getLogger(StrategyExecutionAspect.class);@Around("execution(* com.example.strategy.*.execute(..))")public Object logStrategyExecution(ProceedingJoinPoint joinPoint) throws Throwable {String strategyName = joinPoint.getTarget().getClass().getSimpleName();Object[] args = joinPoint.getArgs();logger.info("Executing strategy: {} with args: {}", strategyName, args);long startTime = System.currentTimeMillis();try {Object result = joinPoint.proceed();long executionTime = System.currentTimeMillis() - startTime;logger.info("Strategy {} executed successfully in {}ms", strategyName, executionTime);return result;} catch (Exception e) {long executionTime = System.currentTimeMillis() - startTime;logger.error("Strategy {} failed after {}ms", strategyName, executionTime, e);throw e;}}
}

总结

策略模式是一种非常实用的设计模式,在Spring框架中得到了广泛应用。通过合理使用策略模式,可以:

  1. 提高代码的可维护性:将算法封装在独立的类中,便于修改和扩展
  2. 增强系统的灵活性:可以在运行时动态选择算法
  3. 降低代码的耦合度:策略与使用策略的客户端解耦
  4. 支持开闭原则:对扩展开放,对修改关闭

在实际应用中,需要注意策略选择机制的设计、策略的生命周期管理、参数传递等重难点问题。通过结合Spring的依赖注入和配置管理,可以构建出更加灵活和可维护的策略系统。


文章转载自:

http://vLt467Bj.cfnsn.cn
http://JgB13sGs.cfnsn.cn
http://sZZHQ40t.cfnsn.cn
http://q1auufSC.cfnsn.cn
http://v1YHyy6O.cfnsn.cn
http://oPpfvzlN.cfnsn.cn
http://E3dy7kF1.cfnsn.cn
http://8A5hAqH5.cfnsn.cn
http://VJiCXNTD.cfnsn.cn
http://PzRmUZfX.cfnsn.cn
http://joHpHFzv.cfnsn.cn
http://xlM6Z9G5.cfnsn.cn
http://tUAGAsTK.cfnsn.cn
http://Wc97aI0k.cfnsn.cn
http://WzcvgEFE.cfnsn.cn
http://3CdKhhGl.cfnsn.cn
http://XvEN0frS.cfnsn.cn
http://TpCwg7mz.cfnsn.cn
http://q5gSjpeY.cfnsn.cn
http://3nfBUiea.cfnsn.cn
http://husPZOVn.cfnsn.cn
http://bsN2vVkI.cfnsn.cn
http://ZqFH9JIo.cfnsn.cn
http://TbhfY2VM.cfnsn.cn
http://eu5d3yDS.cfnsn.cn
http://0AAv7oUh.cfnsn.cn
http://ZJLVOwQe.cfnsn.cn
http://hhdDBqsz.cfnsn.cn
http://8TeVsqCD.cfnsn.cn
http://Mr1yVgPt.cfnsn.cn
http://www.dtcms.com/a/377600.html

相关文章:

  • 洛谷P3405 [USACO16DEC] Cities and States S (哈希表法)详解
  • Vue3纯前端同源跨窗口通信移动AGV小车
  • 4.6Vue的OptionApi
  • qqq数据结构补充
  • 【Vue2】解决数组监听问题
  • 2025 AI+SEO实战学习资料合集,入门到精通的实操指南
  • AutoTrack-IR-DR200构建栅格地图全解析:为教育领域打造的SLAM学习实践平台
  • mysql分库分表数据量核查问题
  • 深入浅出理解查找算法:从基础到实践
  • 最简单解决GitHub打不开的问题:Fastgithub的使用
  • 2025树莓派5烧录镜像教程
  • Ruoyi-vue-plus-5.x第七篇多租户与权限管理:7.2 租户管理功能
  • 解释器模式(Interpreter Pattern)解析与C++实现
  • 《软件方法》2025版 第2章 业务建模之愿景 Part1(20250908更新)
  • 贪心算法(最优装载问题)
  • JavaWeb04
  • ARM处理器的NEON技术
  • 遥感卫星技术解析:全色、多光谱、高光谱与雷达卫星的底层差异及典型应用案例
  • 吴恩达机器学习笔记(8)—神经网络:反向传播算法(附代码)
  • 仓颉安装文档
  • Product Hunt 每日热榜 | 2025-09-09
  • 大数据毕业设计-大数据-基于大数据的热门游戏推荐与可视化系统(高分计算机毕业设计选题·定制开发·真正大数据)
  • 解读数据仓库知识培训【附全文阅读】
  • LangChain中的Prompt模板如何使用?
  • 防逆流·易安装·高兼容——安科瑞ADL200N-CT/D16-WF阳台光伏电表
  • 性能优化零成本:只加3行代码,FCP从1.8s砍到1.2s
  • 深入 Spring MVC 底层:控制器方法执行流程与参数绑定原理解析
  • UniApp微信小程序-实现蓝牙功能
  • Java集成SmartJavaAI实现旋转框检测、定向边界框目标检测(YOLO-OBB)
  • FreeBSD系统使用freebsd-update命令从14.2升级到14.3