设计模式可以替换if语句

时间:2015-07-23 07:13:53

标签: java spring-mvc design-patterns

我们的应用越来越复杂,它主要有3个流程,并且必须基于3种类型之一进行处理。其中许多功能相互重叠。

所以目前代码完全是if-else语句,它们都搞砸了并且没有组织。如何制作一个模式,使3个流清晰地相互分离,但利用可重用性的力量。

请提供一些想法,这是一个MVC应用程序,我们需要使用jaxb技术生成和使用Web服务。

可能您可以将应用程序视为单个对象作为输入,需要根据运行时值实现不同的策略。

4 个答案:

答案 0 :(得分:7)

如果没有对应用程序结构进行一些描述或概述,您的问题就会非常广泛,几乎无法回答。但是,我处于类似情况,这就是我采取的方法:

尽可能用多态性替换条件

  

它主要有3个流程,并且必须基于这3个中的一个进行处理   类型。其中许多功能相互重叠。

你说你的项目有3个主要流程,而且大部分代码都相互重叠。这听起来像是一种策略模式:

您声明一个接口,用于定义Flow执行的任务。

public interface Flow{
   public Data getData();
   public Error validateData();
   public void saveData();
   public Error gotoNextStep();
}

您创建一个抽象类,提供所有3个流共有的实现。 (这个抽象类中的方法不必是最终的,但你肯定要仔细考虑它。)

public abstract class AbstractFlow{

   private FlowManager flowManager

   public AbstractFlow(FlowManager fm){
    flowManager = fm;
   }

   public final void saveData(){
       Data data = getData();
       saveDataAsXMl(data);
   }

   public final Error gotoNextStep(){

      Error error = validateData();
      if(error != null){
         return error;
      }

      saveData();
      fm.gotoNextStep();
      return null;
   }
}

最后,您创建了3个从抽象类扩展的具体类,并定义了给定流的具体实现。

public class BankDetailsFlow extends AbstractFlow{

   public BankDetailsData getData(){
     BankDetailsData data = new BankDetailsData();
     data.setSwiftCode(/*get swift code somehow*/);
     return data;
   }

   public Error validateData(){
      BankDetailsData data = getData();
      return validate(data);
   }

   public void onFormSubmitted(){
      Error error = gotoNextStep();
      if(error != null){
        handleError(error);
      }
   }
}

答案 1 :(得分:7)

您没有指定if-else语句正在执行的操作。假设他们filter取决于某些value

如果我正确理解您的问题,您需要查看Factory Pattern

这是一种干净的方法,易于维护并产生可读代码。添加或删除Filter也很简单,只需删除该类并将其从FilterFactory hashmap中删除。

创建界面:过滤器

 public interface Filter {
    void Filter();
 }

创建一个工厂,根据您的value返回正确的过滤器。现在,您只需使用以下内容代替if-else

  Filter filter = FilterFactory.getFilter(value);
  filter.filter();

编写FilterFactory的一种常用方法是在其中使用HashMap

public class FilterFactory{
   static HashMap<Integer, Filter> filterMap;
   static{
       filterMap = new HashMap<>();
       filterMap.put(0,new Filter0());
       ...
   }
   // this function will change depending on your needs
   public Filter getFilter(int value){
       return filterMap.get(value);
   }

}

创建你的三个(在你的情况下)像这样的过滤器:(虽然名字有意义)

public class Filter0 implements Filter {

    public void filter(){
      //do something
    }
}

注意:由于您要重用某些方法,请创建一个FilterUtility类,并使所有过滤器扩展此类,以便您可以使用所有函数而无需重写它们。

答案 2 :(得分:3)

让我们举个例子,假设你有模型说“数据”[它有一些属性和getter,setter,可选方法]。在移动应用程序的上下文中,特别是Android应用程序可以有两种模式离线或开 - 线。如果设备连接到网络,则数据被发送到网络,否则存储到设备的本地数据库。 在程序方面,有人可以将两个模型定义为OnlineData,OfflineData并将代码写为[代码不精确,它就像伪代码]:

if(Connection.isConnected()){
   OnlineData ond=new OnlineData();
   ond.save();//save is called which stores data on server using HTTP.
}
else{
   OfflineData ofd=new Onlinedata();
   ofd.save();//save is called which stores data in local database
}

实现这一目标的一个好方法是使用OOPS原则:

程序接口而非实现

让我们看看如何做到这一点。 我只是编写代码片段,它将更有效地代表我的意思。片段如下:

public interface Model {
   long save();//save method 
   //other methods .....
}


public class OnlineData extends Model {
  //attributes  
  public long save(){
    //on-line implementation of save method for Data model
  }
  //implementation of other methods.
}

public class OfflineData extends Model {
  //attributes  
  public long save(){
    //off-line implementation of save method for Data model
  }
  //implementation of other methods.
}
public class ObjectFactory{
   public static Model getDataObject(){
     if(Connection.isConnected())
         return new OnlineData();
     else 
         return new OfflineData();

  }
}

以下是您的客户端类应使用的代码:

public class ClientClass{
    public void someMethod(){
      Model model=ObjectFactory.getDataObject();  
      model.save();// here polymorphism plays role...
   }
}

这也是:

单一责任原则[SRP]

因为On-line和Off-line是两个不同的职责,我们可以使用if-else语句在Single save()中集成。

答案 3 :(得分:0)

经过一段时间后,我发现了开源规则引擎框架,例如&#34; drools &#34;是一个很好的选择,以满足我的要求。