一长串if / else / execute代码分支的最佳设计模式/方法

我有一个“遗留”代码,我想重构。
代码基本上是对服务器进行远程调用并获得回复。 然后根据回复执行相应的。
代码骨架示例:

public Object processResponse(String responseType, Object response) { if(responseType.equals(CLIENT_REGISTERED)) { //code //code ... } else if (responseType.equals(CLIENT_ABORTED)) { //code //code.... } else if (responseType.equals(DATA_SPLIT)) { //code //code... } etc 

问题是有很多if / else分支,并且每个内部的代码都不是微不足道的。
因此很难维护。
我想知道这个最好的模式是什么?
我有一个想法是创建一个方法名称与responseType相同的单个对象,然后在processResponse内部使用reflection调用与responseType同名的方法。
这将清理processResponse,但它会将代码移动到具有许多/多种方法的单个对象,我认为reflection会导致性能问题。
是否有一个很好的设计方法/模式来清理它?

两种方法:

  1. 战略模式http://www.dofactory.com/javascript/strategy-design-pattern
  2. 创建字典,其中key是元数据(在您的情况下元数据是responseType),value是函数。

例如:

把它放在构造函数中

responses = new HashMap(); responses.Put(CLIENT_REGISTERED, new ImplementationForRegisteredClient()); responses.Put(CLIENT_ABORTED, new ImplementationForAbortedClient());

其中ImplementationForRegisteredClientImplementationForAbortedClient实现SomeAbstraction

并通过responses.get(responseType).MethodOfYourAbstraction(SomeParams);调用此字典responses.get(responseType).MethodOfYourAbstraction(SomeParams);

如果您想遵循DI原则,可以在客户端类中注入此Dictionary。

我的第一个切割是用switch / case替换if / else if结构:

 public Object processResponse(String responseType, Object response) { switch(responseType) { case CLIENT_REGISTERED: { //code ... } case CLIENT_ABORTED: { //code.... } case DATA_SPLIT: { //code... } 

从那里我可能会提取每个块作为一种方法,并从那里应用策略模式。 在任何感觉正确的地方停下来。

您描述的案例似乎完全适合策略模式的应用。 特别是,您有许多算法变体,即根据远程服务器调用的响应执行的代码。

实现Stategy模式意味着您必须定义一个类层次结构,如下所示:

 public interface ResponseProcessor { public void execute(Context ctx); } class ClientRegistered implements ResponseProcessor { public void execute(Context ctx) { // Actions corresponding to a client that is registered // ... } } class ClientAborted implements ResponseProcessor { public void execute(Context ctx) { // Actions corresponding to a client aborted // ... } } // and so on... 

Context类型应包含执行每个“策略”所需的所有信息。 请注意,如果不同的策略共享一些算法片段,您也可以使用其中的Templeate方法模式

您需要工厂在运行时创建特定策略。 工厂将根据收到的回复制定战略。 可能的实现应该是@Sattar Imamov建议的实现。 工厂将包含if .. else代码。

如果策略类不需要构建,并且在构建时不需要任何外部信息,您还可以将每个策略映射到Enumeration的值。

 public enum ResponseType { CLIENT_REGISTERED(new ClientRegistered()), CLIENT_ABORTED(new ClientAborted()), DATA_SPLIT(new DataSplit()); // Processor associated to a response private ResponseProcessor processor; private ResponseType(ResponseProcessor processor) { this.processor = processor; } public ResponseProcessor getProcessor() { return this.processor; } }