策略模式

2022-05-22  本文已影响0人  世间哪有坦途

一、策略模式的定义

策略模式:定义一系列算法,封装每个算法,并使他们可以互换,不同的策略可以让算法独立于使用它们的客户而变化。

以上定义来自《设计模式之美》,翻译过来就是说,把一系列具有相似特性可以互相替换的算法或业务逻辑通过继承自相同接口或父类的子类进行单独封装,以使得调用者在调用时可以根据不同场景动态替换调用的逻辑。

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合

二、对策略模式优点的思考

  1. 干掉if/else
            看过许多博主甚至是培训机构的老师在讲解策略模式时说可以用策略模式替换掉代码中的if/else,针对这个问题我迷茫了好久,在我看来,策略模式并没有消除掉if/else,只是让其以另一种形式存在而已,业务逻辑最终还是要通过不同形式的分派来决定执行哪种逻辑,所以最终并没有在广义范围上干掉if/else
  2. 封装业务逻辑
            我觉得策略模式最大的优点就是可以将冗长的代码通过实现类的方式单独封装起来,已达到代码隔离的作用方便后期优化以及客户端调用的动态调整,但是任何设计模式都有其有优缺点策略模式也不例外,当业务逻辑或者算法的种类很多的话会造成类爆炸此为其一,有时候一些公共的代码没必要每个实现类都再写一遍,但通过抽象继承的方式实现代码共用又可能增加代码的可读性导致维护难度增大此为其二。

总结下来,策略模式有其优缺点,具体还要根据业务逻辑去决定是否使用。

三、策略模式的实现

image.png

以上是策略模式的UML类结构图

  1. Map+Function实现策略模式
@Service
public class BizService {

    /**
     * 传统的 if else 解决方法
     * 当每个业务逻辑有 3 4 行时,用传统的策略模式不值得,直接的if else又显得不易读
     */
    public String getCheckResult(String order) {
        if ("校验1".equals(order)) {
            return "执行业务逻辑1";
        } else if ("校验2".equals(order)) {
            return "执行业务逻辑2";
        }else if ("校验3".equals(order)) {
            return "执行业务逻辑3";
        }else if ("校验4".equals(order)) {
            return "执行业务逻辑4";
        }else if ("校验5".equals(order)) {
            return "执行业务逻辑5";
        }else if ("校验6".equals(order)) {
            return "执行业务逻辑6";
        }else if ("校验7".equals(order)) {
            return "执行业务逻辑7";
        }else if ("校验8".equals(order)) {
            return "执行业务逻辑8";
        }else if ("校验9".equals(order)) {
            return "执行业务逻辑9";
        }
        return "不在处理的逻辑中返回业务错误";
    }

    /**
     * 业务逻辑分派Map
     * Function为函数式接口,下面代码中 Function<String, String> 的含义是接收一个Stirng类型的变量,返回一个String类型的结果
     */
    private Map<String, Function<String, String>> checkResultDispatcherMuti = new HashMap<>();

    /**
     * 初始化 业务逻辑分派Map 其中value 存放的是 lambda表达式
     */
    @PostConstruct
    public void checkResultDispatcherInit() {
        checkResultDispatcherMuti.put("key_订单1", order -> String.format("对%s执行业务逻辑1", order));
        checkResultDispatcherMuti.put("key_订单1_订单2", order -> String.format("对%s执行业务逻辑2", order));
        checkResultDispatcherMuti.put("key_订单1_订单2_订单3", order -> String.format("对%s执行业务逻辑3", order));
    
    }

  /**
     * 判断条件方法
     */
    private String getDispatcherKey(String order, int level) {
        StringBuilder key = new StringBuilder("key");
        for (int i = 1; i <= level; i++) {
            key.append("_" + order + i);
        }
        return key.toString();
    }

    public String getCheckResultMuti(String order, int level) {
        //写一段生成key的逻辑:
        String key = getDispatcherKey(order, level);

        Function<String, String> result = checkResultDispatcherMuti.get(key);
        if (result != null) {
            //执行这段表达式获得String类型的结果
            return result.apply(order);
        }
        return "不在处理的逻辑中返回业务错误";
    }
}

controller 方法:

/**
 * 模拟一次http调用
 */
@RestController
public class BizController {

    @Autowired
    private BizService bizService;

    @PostMapping("/v1/biz/testMuti")
    public String test1(String order, Integer level) {
        return bizService.getCheckResultMuti(order, level);
    }
}

四、策略模式和工厂模式的区别

总结下来就是,工厂模式对应的是实例对象,该对象可能有很多继承的方法或者没有;策略模式对应的是具体某个行为也即方法或者叫算法。

上一篇 下一篇

猜你喜欢

热点阅读