【学习打卡】第十天 Java设计模式精讲-Debug方式+内存分析 第十九讲
课程名称:Java设计模式精讲-Debug方式+内存分析,真正学懂设计模式
课程章节: 策略模式+Coding+源码解析
主讲老师:Geely
课程内容:
今天学习的内容包括:
什么是策略模式 策略模式 优点 缺点 Coding 源码解析 以及在业务上的应用
课程收获:
GOF的《设计模式》著作中认为策略模式可以消除一些条件语句,我对此持怀疑态度。正如上面的例子,虽然由于Context在初始化的时候已经指定了策略实现,在计算逻辑中不需要根据条件选择逻辑分支。但是,客户端代码在初始化Context的时候,如何判断应该传入哪个策略实现呢?其实在客户端代码或者别的地方还是缺少不了条件判断。所以这里消除条件语句,只是针对算法逻辑的条件判断。
2. 策略模式优缺点
那么策略模式的优点是什么了?
2.1 优点
1. 使用策略模式 可以根据策略接口 定义一系列可供复用的行为和算法;
2. 调用方只需要持有context 的引用即可 而无需知道具体策略实现 满足迪米特法则;
3. context在策略的方法之外可以做一些通用的切面逻辑
2.2 缺点
1. 客户端代码需要知道不同的策略以及如何选择策略。因此可以看到上面的客户端代码有着丑陋的条件判断;
2. 由于策略类实现同样的接口,所以参数列表要保持一致,但可能并不是所有的策略都需要全部参数
## 3. 策略模式与工厂模式结合使用
针对第一个缺点。我们可以通过策略模式与工厂模式结合使用来改进。通过进一步封装,消除客户端代码的条件选择
代码如下
package com.zw.design.pattern.behavioral.mianshi; /**** * 定义一个动物类的接口 实现策略 */ public interface IAnimalStrategy { public void doPromotion() ; }
package com.zw.design.pattern.behavioral.mianshi; /*** * 定义一个猫的类 实现动物的接口 */ public class CatStrategy implements IAnimalStrategy { @Override public void doPromotion() { System.out.println("这个是处理猫的类"); } } ``` ```java package com.zw.design.pattern.behavioral.mianshi; /*** * 定义一个狗 实现动物策略接口 */ public class DogStrategy implements IAnimalStrategy { @Override public void doPromotion() { System.out.println("处理dog行为"); } }
package com.zw.design.pattern.behavioral.mianshi; /*** * 定义一个空策略类 实现动物策略接口 */ public class EmptyAnimalStrategy implements IAnimalStrategy { @Override public void doPromotion() { } }
package com.zw.design.pattern.behavioral.mianshi; /*** * 这是pig 类实现动物策略接口类 */ public class PigStrategy implements IAnimalStrategy { @Override public void doPromotion() { System.out.println("这是pig的类"); } }
package com.zw.design.pattern.behavioral.mianshi; import java.util.HashMap; import java.util.Map; //这是一个抽象工厂 用来生产所有实现过策略模式的类 public abstract class AnimalStrategyFactory { //定义一个 静态的 常量的map 集合 private final static Map<String, IAnimalStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, IAnimalStrategy>(); //定义三个常量 并且是final 而且带分组功能 private interface PromotionKey{ String DOG = "dog"; String PIG = "pig"; String CAT = "cat"; } /*** * 根据你传入的key 返回一个具体促销的类 实现可扩展 * @param promotionKey * @return */ public static IAnimalStrategy getPromotionStrategy(String promotionKey){ IAnimalStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey); // return promotionStrategy == null ? null : promotionStrategy; //为了业务 更友好的模式 这里不能返回null 所以定义一个无促销活动的类 return promotionStrategy == null ? NON_PROMOTION : promotionStrategy; } //定义一个无促销的活动类 private static final IAnimalStrategy NON_PROMOTION = new EmptyAnimalStrategy(); //使用静态代码块进行往map 里面放入值 放入具体的策略的值 static { PROMOTION_STRATEGY_MAP.put(PromotionKey.CAT,new CatStrategy()); PROMOTION_STRATEGY_MAP.put(PromotionKey.DOG,new DogStrategy()); PROMOTION_STRATEGY_MAP.put(PromotionKey.PIG,new PigStrategy()); } }
package com.zw.design.pattern.behavioral.mianshi; /*** * 使用策略模式的客户端 */ public class AnimalActivity { //放入动物策略的具体类 这里丢入接口 多态思想 private IAnimalStrategy promotionStrategy; public AnimalActivity(IAnimalStrategy promotionStrategy){ this.promotionStrategy = promotionStrategy; } //有个具体的行为 public void executePromotionStrategy(){ promotionStrategy.doPromotion(); } } //测试 public static void main(String[] args) { String petType="dog"; AnimalActivity animalActivity=new AnimalActivity( AnimalStrategyFactory.getPromotionStrategy(petType) ); animalActivity.executePromotionStrategy(); }
## 4. 策略模式适用场景
当存在多种逻辑不同,但属于同一类型的行为或者算法时,可以考虑使用策略模式。以此来消除你算法代码中的条件判断。同时让你的代码满足多种设计原则。
很多时候,工厂模式和策略模式都可以为你解决同类问题。但你要想清楚,你想要的是一个对象,还是仅仅想要一个计算结果。如果你需要的是一个对象,并且想用它做很多事情。那么请使用工厂模式。而你仅仅想要一个特定算法的计算结果,那么请使用策略模式。
策略模式属于对象行为模式,而工厂属于创建型模式。策略模式和工厂模式对比如下:
5. 小结
策略模式解决的问题是如何封装可供复用的算法或者行为。策略模式满足了单一职责、开闭、迪米特法则、依赖倒转等原则。我们一定想清楚策略模式的适用场景,否则某些时候你会搞不清到底用工厂模式还是策略模式。最后提醒大家,设计模式很多时候都是混合使用,我们不应该局限于使用某一种设计模式来解决问题。
## 6.jdk和spring当中具体典型案例
jdk Comparator 比较器最佳策略模式实现
jdk TreeMap 当中 compare 方法也是策略模式的典型应用
Resource spring 当中 org.springframword.core.io 包下 当它实现类
我们可能经常用比如ClassPathResource还有文件FileSystemResource
Spring 当中Bean的初始化也是用这个类 InstantiationStrategy 它的
实现类有两个 一个是Cglib的初始化类子类
还有一个是简单的初始化策略 策略和策略之间可以存在继承关系
总结:今天学习课程共用了2个小时,重新学习一下设计模式 更加清楚知道策略模式的应用以及如何在自己项目当中去使用它 大家一起加油 💪🏻
共同学习,写下你的评论
评论加载中...
作者其他优质文章