Java利用策略模式优化过多if else代码

前言

不出意外,这应该是年前最后一次分享,本次来一点实际开发中会用到的小技巧。

比如平时大家是否都会写类似这样的代码:

if(a){
 //dosomething
}else if(b){
 //doshomething
}else if(c){
 //doshomething
} else{
 ////doshomething
}

条件少还好,一旦 else if 过多这里的逻辑将会比较混乱,并很容易出错。

比如这样:

摘自cim中的一个客户端命令的判断条件。

刚开始条件较少,也就没管那么多直接写的;现在功能多了导致每次新增一个 else 条件我都得仔细核对,生怕影响之前的逻辑。

这次终于忍无可忍就把他重构了,重构之后这里的结构如下:

最后直接变为两行代码,简洁了许多。

而之前所有的实现逻辑都单独抽取到其他实现类中。

这样每当我需要新增一个 else 逻辑,只需要新增一个类实现同一个接口便可完成。每个处理逻辑都互相独立互不干扰。

实现

按照目前的实现画了一个草图。

整体思路如下:

  • 定义一个 InnerCommand 接口,其中有一个 process 函数交给具体的业务实现。
  • 根据自己的业务,会有多个类实现 InnerCommand 接口;这些实现类都会注册到 Spring Bean 容器中供之后使用。
  • 通过客户端输入命令,从 Spring Bean 容器中获取一个 InnerCommand 实例。
  • 执行最终的 process 函数。

主要想实现的目的就是不在有多个判断条件,只需要根据当前客户端的状态动态的获取 InnerCommand 实例。

从源码上来看最主要的就是 InnerCommandContext 类,他会根据当前客户端命令动态获取 InnerCommand 实例。

  • 第一步是获取所有的 InnerCommand 实例列表。
  • 根据客户端输入的命令从第一步的实例列表中获取类类型。
  • 根据类类型从 Spring 容器中获取具体实例对象。

因此首先第一步需要维护各个命令所对应的类类型。

所以在之前的枚举中就维护了命令和类类型的关系,只需要知道命令就能知道他的类类型。

这样才能满足只需要两行代码就能替换以前复杂的 if else,同时也能灵活扩展。

InnerCommand instance = innerCommandContext.getInstance(msg);
instance.process(msg) ;

总结

当然还可以做的更灵活一些,比如都不需要显式的维护命令和类类型的对应关系。

只需要在应用启动时扫描所有实现了 InnerCommand 接口的类即可,在 cicada 中有类似实现,感兴趣的可以自行查看

这样一些小技巧希望对你有所帮助。

以上所有源码可以在这里查看:
https://github.com/crossoverJie/cim

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现策略模式使用示例

    思路如下: 使用interface来定义一个接口,在该接口中定义save()方法:根据图片格式定义不同的类,分别在这些类中使用关键字implements实现接口:创建一个实现选择的类,在该类中定义实现选择的方法,该方法返回值为对应的图片保存类:在主方法中实现接口.代码如下: 复制代码 代码如下: public interface ImageSaver {    void save();//定义save()方法} public class GIFSaver implements ImageSave

  • Java设计模式之策略模式原理与用法实例详解

    本文实例讲述了Java设计模式之策略模式原理与用法.分享给大家供大家参考,具体如下: 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化.其中JDK里面的TreeSet类和TreeMap类就用到了策略模式.这两个类是带排序的集合类,其中排序的规则就相当于策略模式里定义的一系列算法,而集合类就相当于是策略模式里的环境类,供用户使用,用只知道TreeSet和TreeMap是带排序的,至于怎么排序的,是由排序的算法决定的. 策略模式

  • 详解Java编程中的策略模式

    策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理.策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类.用一句话来说,就是:"准备一组算法,并将每一个算法封装起来,使得它们可以互换".下面就以一个示意性的实现讲解策略模式实例的结构. 这个

  • 详解Java设计模式编程中的策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 类图: 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过的行为类模式中,有一种模式也是关注对算法的封装--模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主体则是封装到了封装类Context中

  • java设计模式学习之策略模式

    策略模式:策略模式是一种定义一系列算法的方法,算法完成的工作都是相同的工作,但是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合. Java实现一个策略模式: 需求:商场收银系统,收银方式为正常收费,打八折,满300返100,这三种收费方式. 1:创建一个超类.即收费的抽象方法. public abstract class CashSuper { public abstract double acceptCash(double money); } 2:创建实现此

  • Java经典设计模式之策略模式原理与用法详解

    本文实例讲述了Java经典设计模式之策略模式.分享给大家供大家参考,具体如下: 策略模式指:策略模式指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式一般由下面三部分组成: 1. 抽象策略角色: 策略类,通常由一个接口或者抽象类实现. 2. 具体策略角色:包装了相关的算法和行为. 3. 环境角色:持有某一个策略类的引用,客户端调用. 策略模式设计原则: 1. 把程序中需要变化的部分抽离出来,独立于不变

  • java 使用策略模式操作JDBC数据库

    java 使用策略模式操作JDBC数据库 1:构造一个操作数据库的工具类,可以获得连接和释放连接 public class DBUtil { private static Connection conn = null; static { //静态初始块 try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/tes

  • 对比Java设计模式编程中的状态模式和策略模式

    为了能在Java应用程序中正确的使用状态模式和策略模式,开发人员需要清楚地知道这两种模式之间的区别.尽管状态模式和策略模式的结构非常相似,它们又同样遵循开闭原则,都代表着SOLID设计原则的'O',但它们的意图是完全不同的.Java中的策略模式是对一组相关的算法进行封装,给调用方提供了运行时的灵活性.调用方可以在运行时选择不同的算法,而不用修改使用策略的那个Context类.使用策略模式的经典例子包括实现加密算法,压缩算法,以及排序算法.另一方面,状态模式使用一个对象可以在不同的状态下表现出不同

  • Java策略模式的简单应用实现方法

    在使用图像处理软件处理图片后,需要选择一种格式进行保存.然而各种格式在底层实现的算法并不相同,这刚好适合策略模式.编写程序,演示如何使用策略模式与简单工厂模式组合进行开发. 思路如下: 1.使用interface来定义一个接口,在该接口中定义save()方法:2.根据图片格式定义不同的类,分别在这些类中使用关键字implements实现接口:3.创建一个实现选择的类,在该类中定义实现选择的方法,该方法返回值为对应的图片保存类:4.在主方法中实现接口.代码如下: 复制代码 代码如下: public

  • 轻松掌握Java策略模式

    定义:一个类的行为或其算法可以在运行时更改.在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象.策略对象改变 context 对象的执行算法. 特点: 1.算法可以自由切换. 2.避免使用多重条件判断. 3.扩展性良好. 企业级开发和常用框架中的应用:java.servlet.http.HttpServlet的service方法 实例:对两个数的操作行为. public class Demo { public static void main(Str

随机推荐