设计模式-策略模式
定义:
策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
优点:
-
算法可以自由切换
-
避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护)
-
扩展性良好,增加一个策略只需实现接口即可
-
提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
缺点:
-
策略类数量会增多,每个策略都是一个类,复用的可能性很小
-
所有的策略类都需要对外暴露
-
只适合偏平的算法结构
角色:
-
抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
-
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
-
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
结构说明:
具体实现:
1、策略接口
1 2 3 4 5 | //策略接口 public interface IStrategy { //定义的抽象算法方法 来约束具体的算法实现方法 public void algorithmMethod(); } |
2、具体策略实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 具体的策略实现1 public class ConcreteStrategy1 implements IStrategy { //具体的算法实现 @Override public void algorithmMethod() { System.out.println( "this is ConcreteStrategy method..." ); } } // 具体的策略实现 public class ConcreteStrategy2 implements IStrategy { //具体的算法实现 @Override public void algorithmMethod() { System.out.println( "this is ConcreteStrategy method..." ); } } |
3、策略上下文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * 策略上下文 */ public class StrategyContext { //持有一个策略实现的引用 private IStrategy strategy; //使用构造器注入具体的策略类 public StrategyContext(IStrategy strategy) { this .strategy = strategy; } public void contextMethod(){ //调用策略实现的方法 strategy.algorithmMethod(); } } |
3、调用策略
1 2 3 4 5 6 | //1.创建具体测策略实现 IStrategy strategy = new ConcreteStrategy2(); //2.在创建策略上下文的同时,将具体的策略实现对象注入到策略上下文当中 StrategyContext ctx = new StrategyContext(strategy); //3.调用上下文对象的方法来完成对具体策略实现的回调 ctx.contextMethod(); |
使用场景
-
多个类只有算法或行为上稍有不同的场景
-
算法需要自由切换的场景
-
需要屏蔽算法规则的场景
spring应用场景:
1、借助Spring 强大的依赖注入,消除if/else
的关键代码,Spring 会自动将 EntStrategy
接口的实现类注入到这个Map中。前提是你这个实现类得是交给Spring 容器管理的。
1 2 3 4 5 6 7 8 9 10 11 | @Component public class EntStrategyHolder { // 关键功能 Spring 会自动将 IStrategy 接口的类注入到这个Map中 @Autowired private Map<String, IStrategy> entStrategyMap; public IStrategy getBy(String entNum) { return entStrategyMap.get(entNum); } } |
具体实现原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Component public class StrategyResolver implements InitializingBean, ApplicationContextAware { private ApplicationContext applicationContext; private Map<String, Sign> StrategyHandlerMap = new HashMap<>(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this .applicationContext = applicationContext; } @Override public void afterPropertiesSet() { Map<String, Sign> beanMap = applicationContext.getBeansOfType(Strategy. class ); for (String key : beanMap.keySet()) { this .StrategyHandlerMap.put(beanMap.get(key).companyCode(), beanMap.get(key)); } } public Strategy getHandler(String companyCode) { return StrategyHandlerMap.get(companyCode); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具