1. 策略模式解决if - else 的代码

业务场景:

外包企业的审批人需要审批打卡的场景;

审批人分为多种不同的级别,多种级别中具有方式相同但是内容不同的操作:审批。

原来场景:

有前端传来审批人参数,使用if-else 来判断该审批人的级别属于哪一个级别,执行相应的审批方法。每一个审批方法写在了业务类底,命名采用1级审批,2级审批---等等的命名方式来命名。

问题:if - else 逻辑复杂,不易阅读,函数中审批能抽象的地方未抽象,

两个核心问题:test测试非常麻烦,新增审批人员需要对代码进行修改,违背开闭原则。

解决过程:

  1. 抽象审批中的原子操作的代码,比如查询对应级别所审批的同学名单。代码变得好看一些,但是任然未解决,if - else 和 多个 审批方法的实现。

  2. 尝试策略模式

    1. 使用策略模式将每个级别的用户抽象起来

      1. package strategy;
      2. public class Main {
      3. public static void main(String[] args) {
      4. if (LevelEnum.LEVEL1.equals(1)) {
      5. SupervisorControl supervisorControl = new SupervisorControl(new Supervisor1());
      6. supervisorControl.execute(1);
      7. }
      8. if (LevelEnum.LEVEL2.equals(2)) {
      9. SupervisorControl supervisorControl = new SupervisorControl(new Supervisor2());
      10. supervisorControl.execute(2);
      11. }
      12. if (LevelEnum.LEVEL3.equals(3)) {
      13. SupervisorControl supervisorControl = new SupervisorControl(new Supervisor3());
      14. supervisorControl.execute(3);
      15. }
      16. }
      17. }
      1. package strategy;
      2. public enum LevelEnum {
      3. LEVEL1, LEVEL2, LEVEL3
      4. }
      1. package strategy;
      2. public interface Supervisor {
      3. void examine(int supervisorId);
      4. }
      1. package strategy;
      2. public class Supervisor1 implements Supervisor {
      3. public void examine(int supervisorId) {
      4. System.out.println("去做一些和1级supervisor相关的工作");
      5. }
      6. }
      1. package strategy;
      2. public class Supervisor2 implements Supervisor {
      3. public void examine(int supervisorId) {
      4. System.out.println("去做一些和2级supervisor相关的工作");
      5. }
      6. }
      1. package strategy;
      2. public class Supervisor3 implements Supervisor {
      3. public void examine(int supervisorId) {
      4. System.out.println("去做一些和3级supervisor相关的工作");
      5. }
      6. }
      1. package strategy;
      2. public class SupervisorControl {
      3. Supervisor supervisor;
      4. public SupervisorControl(Supervisor supervisor) {
      5. this.supervisor = supervisor;
      6. }
      7. public void execute(int id) {
      8. supervisor.examine(id);
      9. }
      10. }

解决方法:

  1. 混合使用策略模式和反射来解决
  1. package strategy;
  2. public class Main {
  3. public static void main(String[] args) {
  4. // if (LevelEnum.LEVEL1.equals(1)) {
  5. // SupervisorControl supervisorControl = new SupervisorControl(new Supervisor1());
  6. // supervisorControl.execute(1);
  7. // }
  8. // if (LevelEnum.LEVEL2.equals(2)) {
  9. // SupervisorControl supervisorControl = new SupervisorControl(new Supervisor2());
  10. // supervisorControl.execute(2);
  11. // }
  12. // if (LevelEnum.LEVEL3.equals(3)) {
  13. // SupervisorControl supervisorControl = new SupervisorControl(new Supervisor3());
  14. // supervisorControl.execute(3);
  15. // }
  16. String packageName = Supervisor1.class.getPackage().getName();
  17. String supervisorName = packageName + "." + "Supervisor" + "2";
  18. try {
  19. Class<?> clazz = Class.forName(supervisorName);
  20. Supervisor supervisor = (Supervisor) clazz.newInstance();
  21. supervisor.examine(1);
  22. } catch (Exception e) {
  23. System.out.println(e);
  24. }
  25. }
  26. }

注意

class.forName() 需要传入的格式是"包名.类名"。如果找不到包名则会报ClassNotFoundException

可以通过class.getPackage来获取包名。


到此我们解决了if - else 很多的问题,并且解决了需要侵入代码修改的问题,如果新增supervisor的级别,只需要和前端达成一致,后台继续写一个supervisor4对象即可。

为什么解决了test难的问题

对于test来说,每一个If-else 都需要我们去验证,这其实就是两个test, if 一个 else一个,如果有很多if - else,想要保证高的test覆盖率,就会非常头痛。

然而我们用策略模式 和 反射来解决,只需要,对主逻辑一个test,每一个实现方法做一个test即可。

至此,所有问题都解决了,代码一片光明。

过多if - else 的问题, 以及策略模式 + 反射解决方法的更多相关文章

  1. Ajax跨域、Json跨域、Socket跨域和Canvas跨域等同源策略限制的解决方法

    同源是指同样的协议.域名.port,三者都同样才属于同域.不符合上述定义的请求,则称为跨域. 相信每一个开发者都曾遇到过跨域请求的情况,尽管情况不一样,但问题的本质都能够归为浏览器出于安全考虑下的同源 ...

  2. 对于使用progisp软件进行ISP编程时进入不了编程模式的解决方法

    标题: 对于使用progisp软件进行ISP编程时无法进入编程模式的解决方法 作者: 梦幻之心星 347369787@QQ.com 标签: [progisp, 软件] 目录: 软件 日期: 2019- ...

  3. AWS AutoScaling的一个ScaleDown策略问题以及解决方法

    此文已由作者袁欢授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1. AWS AutoScaling简介 AutoScaling是AWS的一个重要服务,用来弹性的自动创建(S ...

  4. 策略模式&反射

    业务代码 class Operate { public string _firstKey; public string _secondKey; public string _extendKey; pu ...

  5. chrome进入控制台时自动进入断点模式的解决方法

    简单粗暴,不知道为什么,去掉那个√就好了

  6. 高并发连接导致打开文件过多:java.io.IOException: Too many open files 解决方法

    用 CentOS 做 API 接口服务器供其他终端调用时,并发量高会报错:java.io.IOException: Too many open files. 其原因是在 Linux 下默认的Socke ...

  7. chrome打开控制台状态下,没有人为打断点,自动进入断点模式的解决方法

    如下图所示:在控制台去掉Sources -> XHR/fetch Breakpoints -> Any XHR or fetch 的勾

  8. Java的设计模式----strategy(策略模式)

    设计模式: 一个程序员对设计模式的理解: “不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开 ...

  9. 【策略模式】策略模式结合Spring实战Demo

    策略模式 策略模式用于解决判断分支过多的问题,使代码变得简洁和优雅, 策略模式在多种方式在项目中落地,下面举例说明通过指定不同类型的订单使用策略模式执行不同的业务逻辑 文章参考自公众号:石杉的架构笔记 ...

随机推荐

  1. Jmeter入门使用

    1. 什么是Jmeter 转自:https://www.cnblogs.com/lijuanhu321/p/9537185.html#testComponent https://www.cnblogs ...

  2. 微服务架构Day05-SpringBoot之Servlet

    旧版 配置嵌入式Servlet容器 SpringBoot默认使用Tomcat作为嵌入式Servlet容器 如何定制和修改Servlet容器相关配置 1.在配置文件中定制和修改Servlet容器有关的配 ...

  3. C#通过NI-VISA操作Tektronix TBS 2000B系列示波器

    一.概述 本文描述采用C#语言访问控制Tektronix TBS 2000B 系列示波器.接口协议采用NI-VISA. 最近一个项目需要和一款示波器进行通信,需要对示波器进行一些简单控制并获取到波形数 ...

  4. free open music API all in one

    free open music API all in one music API SoundCloud xgqfrms · free https://w.soundcloud.com/player/? ...

  5. TS type different String / string

    TS type different String / string String / string https://stackoverflow.com/questions/14727044/types ...

  6. linux bash shell & lsof & grep & ps

    linux bash shell & lsof & grep & ps lsof list all open files # lsof & grep $ lsof -P ...

  7. 调整是为了更好的上涨,牛市下的SPC空投来了!

    2021年刚过没几天,比特币就开启了牛市的旅程,BTC涨到4万美元,ETH涨到1300多美元,BGV也涨到了621.05美元,牛市已然来袭. 虽然从近两日,比特币带领着主流币进行了一波调整,但是只涨不 ...

  8. TYLER ADAMS BRADBERRY的私人投资分享

    TYLER ADAMS BRADBERRY是星盟全球投资公司(USA International Covenant 公司编号:20091457685)的创始人.投资委员会发起了15支项目基金,通过多方 ...

  9. mysql一张表到底能存多少数据?

    前言 程序员平时和mysql打交道一定不少,可以说每天都有接触到,但是mysql一张表到底能存多少数据呢?计算根据是什么呢?接下来咱们逐一探讨 知识准备 数据页 在操作系统中,我们知道为了跟磁盘交互, ...

  10. 使用 Castle 实现 AOP,以及 Autofac 集成 Castle

    Castle 是 2003 年诞生于 Apache Avalon 项目,目的是为了创建一个IOC 框架.发展到现在已经有四个组件: ORM组件:ActiveRecord IOC组件:Windsor 动 ...