如何优雅的解决多重分支问题

    相信在实际开发中,一定会遇到这样的问题:一条业务线,因为种种原因有了不同的业务走向,可能会出现好多个分支。随着业务越做越大,if和else已经无法满足需求了,只能不停地加方法来分离业务了。但是,if和else的魔咒始终都在。

   为了解决上述问题,可能要做很多额外的工作来简化我们的代码。那么,有没有一种特别简单的实现方式呢?现在我们想象这样一个场景,你的顶头上司告诉你某业务很复杂,需要你来做。复杂的点是有十个业务分支你需要实现,且不允许在代码中使用if和else来堆代码。要求代码结果清晰明了,通俗易读。

        头大不?作为一个优秀的程序员,当然不能只满足于堆代码这种无聊的事吧?接下来,我们一起实现这个艰难的任务。如果不用if和else,怎么完成不同分支的走向呢?

       首先,按照以前的思路,既然有十个分支,那么,它们肯定有相同点吧?提取一个公共方法,然后根据不同的分支用if来选择就好啦!基于这个思路,相信之前的你已经可以写出这样的代码了:

@Component
public class MainTest{

   public Object void  main(){
       return doBranch(参数);
   }

   public Object doBranch(参数){
 
        //do something
   }
}

    这是我们想要的吗?当然不是! 这种传统的doBranch()方法里我们能做的只是用if来判断去判断要执行哪个分支,还是要有十个if来分发发业务。那么,我们怎么把这十个业务完全分开呢?比如,写到不同的业务类里?

     所以,我们先定义一个接口,长这样:

public interface BranchInterface{

    public Object doBranch(参数);
}

    然后,写十个像这样的BranchInterface接口的实现类?

public class branch1 implements BranchInterface{

    public Object doBranch(参数){

    }
}

  恩,没错。走到这一步,已经是一个很大的进步了。至少,代码都给拆开了,没那么乱了。但是,能离得开if和else吗?貌似不能诶。主分支里,甚至需要new十个java对象来选择不同的分支诶!等等,让自己的思绪停下来,谁说java对象必须new的?用spring的Bean注入啊!来来来,让我们继续往下走。所有的分支业务类,都实现了同一个java 接口,所以,首先可以确定一件事,那就是可以用Bean注入的方法分支实现类!所以,我们的主业务线需要改改了,改成这样:

@Component
public class MainTest{

   @Autowired
   private BranchInterface branch;

   public Object void  main(参数){
       return branch.doBranch(参数);
   }

}

诶,不对吧,十个分支,这样搞的话,根本不知道要注入哪个吧?好,用@Resource来试试?困惑ing....

好了,解决办法来了。想想我们的需求是什么?在运行期根据实际业务需求来动态选择业务实现类,是这样吧?那我们换种方式来注入Bean(Spring获取Bean的几种方式百度了解下)。

@Component
public class MainTest implements ApplicationContextAware{

   private ApplicationContext applicationContext;

   private BranchInterface branch;

   public Object void  main(参数){
       Map<String, BranchInterface> branchs = applicationContext..getBeansOfType(BranchInterface.class);
       for(String branchName: branchs.keyset()){
           branch = branchs.get(branchName);
           branch.doBranch(参数);
       }
       return null;
   }

  public void setApplicationContext(ApplicationContext context) {
    this.applicationContext = context;
  }
}

     如上,我们换了一种获取分支业务类的方式,通过ApplicationContextAware接口注入applicationContext,然后从applicationContext里取出所有实现了BranchInterface接口的业务类。然后就可以根据需求调用分支方法了(看不懂的话,反思下自己每天都在干啥了。。。)。

   那么问题又来了,十个业务类,哪个才是我想要的呢?难道绕了一圈又回到if和else了么?当然不是。我们想象为什么会有十个分支?为什么,难道不是因为需求么?好,那我们给每个需求分配一个分支key,可以吗?再进入这块的业务前,就已经把它们都定义好了行不行?所以,改造下我们的主干业务类:

@Component
public class MainTest implements ApplicationContextAware{

   private ApplicationContext applicationContext;

   private BranchInterface branch;

   public Object void  main(String key,参数){
       Map<String, BranchInterface> branchs = applicationContext..getBeansOfType(BranchInterface.class);
       return branchs.get(key).doBranch(参数);
   }

  public void setApplicationContext(ApplicationContext context) {
    this.applicationContext = context;
  }
}

BranchInterrface接口和其实现类也做同样的扩展。注意到上面的代码还做了什么改动没?没错,直接把分支的key当做分支实现类的Bean名了!这样一来,还需要if吗?恭喜在座的各位,我们完成了一波优雅的业务解耦合!十个分支,一个if都没出现!

猜你喜欢

转载自blog.csdn.net/qq_28802119/article/details/88951667