策略设计模式
策略设计模式主要解决的问题是:当你的代码中需要根据具体的场景来选择相应的策略逻辑来实现时。
对于代码层面主要的优化点在:你的代码在一个类中写了很多的if else 之类的判断,并且在每个if 判断中有相应的代码逻辑的实现。这时你就需要考虑将每个if中的判断逻辑抽象
出一个类,这样对于每块判断逻辑便于维护。
核心代码:
1:每个if判断逻辑维护一个类来实现这部分逻辑,称这个类为策略类
2:维护一个策略容器(其实就是维护一个map),策略容器中包含所有的策略类
下面看看具体的的策略模式的代码实现
场景:假设现在项目中需要用到分享的功能,将内容分享到 qq 微信 sina 三个平台上 后续可能还会增加分享的平台。
没有使用策略模式的情况下,代码的实现如下所示:所有的实现逻辑都写在一个类中;
public class NoStrategy { // 处理分享的逻辑根据类型进行逻辑 这里分享有3种情况 1:qq分享 2:微信分享 3:头条分享 public void handleShare(String type, Map<String,String> requestMap){ //假设所有的分享都分为3个步骤 1:解析入参map数据 2:封装分享需要的数据 3 调用分享的接口 if("qq".equals(type)){ // 进入qq分享的逻辑 doQQShare(requestMap); }else if("wechat".equals(type)){ //进入 微信分享的逻辑 doWechatShare(requestMap); }else if("toutiao".equals(type)){ //进入头条分享的逻辑 doToutiaoShare(requestMap); } } // qq 分享逻辑 private void doQQShare(Map<String,String> requestMap){ // 1:解析 map 数据 // 2 封装分享需要的数据 // 3 调用分享的接口 } // wechat 分享逻辑 private void doWechatShare(Map<String,String> requestMap){ // 1:解析 map 数据 // 2 封装分享需要的数据 // 3 调用分享的接口 } // 头条 分享逻辑 private void doToutiaoShare(Map<String,String> requestMap){ // 1:解析 map 数据 // 2 封装分享需要的数据 // 3 调用分享的接口 } }
不使用策略实现代码有以下特点:
1:代码逻辑中有很多的 if else 的判断,当增加一个分享的平台的时候又需要增加一个判断,这个维护了所有逻辑的类要做更改,代码维护性不够好。
2:代码的所有逻辑都写在一个类中,不便于后期扩展,因为增加一种分享平台的情况很常见,而增加一个就需要改主逻辑的代码
下面再对比一下使用策略模式后的编码:
1:维护一个分享策略的接口,具体的分享实现类实现这个接口
1 public interface ShareStrategy { 2 3 void doShare(); 4 5 }
2:具体的分享的类 qq 分享 wechat 分享 sina 分享
1 public class QQShare implements ShareStrategy { 2 3 @Override 4 public void doShare() { 5 // 1:解析 map 数据 6 // 2 封装分享需要的数据 7 // 3 调用分享的接口 8 } 9 }
public class WechatShare implements ShareStrategy { @Override public void doShare() { // 1:解析 map 数据 // 2 封装分享需要的数据 // 3 调用分享的接口 } }
public class SinaShare implements ShareStrategy{ @Override public void doShare() { // 1:解析 map 数据 // 2 封装分享需要的数据 // 3 调用分享的接口 } }
3:维护一个策略容器,策略容器可以使用一个map容器来维护,策略容器可以在类加载的时候进行初始化,或者在项目启动的时候进行初始化,将策略实现类加载到容器中。
public class StrategyContext { private static Map<String, ShareStrategy> context; static { context = new HashMap<>(); context.put("qq", new QQShare()); context.put("wechat", new WechatShare()); context.put("sina", new SinaShare()); } public static ShareStrategy getShareStrategyTarget(String type) { ShareStrategy ss = context.get(type); return ss; } }
接下来要调用具体的策略的时候就不需要通过 if else 来进行判断了,只需要通过传过来的type 获取到具体的策略实现类后执行相应的方法即可。
@Test public void testStrategy1(){ // 策略模式测试 全策略 各自的实现维护在单独的勒种,维护一个策略容器 从策略容器中获取相应的策略实现 String type="qq"; //策略类型 0 qq 1 wechat 2 sina ShareStrategy target = StrategyContext.getShareStrategyTarget(type); target.doShare(); }
这样当需要新增一种分享策略的时候,只需要新增一个策略实现类,然后将该实现类添加到策略容器中即可。对主逻辑的代码实现不用更改,实现了对新增开放对修改关闭的原则。
到这里策略模式已经over了。