zoukankan      html  css  js  c++  java
  • 策略设计模式

    策略设计模式主要解决的问题是:当你的代码中需要根据具体的场景来选择相应的策略逻辑来实现时。

    对于代码层面主要的优化点在:你的代码在一个类中写了很多的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了。

  • 相关阅读:
    [BZOJ4825][HNOI2017]单旋(线段树+Splay)
    [BZOJ4542][HNOI2016]大数(莫队)
    [LOJ6281]数列分块入门 5
    [LOJ6280]数列分块入门 4
    [LOJ6279]数列分块入门 3
    [LOJ6278]数列分块入门 2
    [LOJ6277]数列分块入门 1
    [BZOJ2120]数颜色
    [BZOJ3585]mex
    [ZJb417]区间众数
  • 原文地址:https://www.cnblogs.com/beppezhang/p/12882120.html
Copyright © 2011-2022 走看看