我有一个“遗留”代码,我想重构。
代码基本上是对服务器的远程调用并获得回复。然后根据回复执行相应的
代码骨架的例子:
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内部使用反射调用与responseType同名的方法。
这会清理processResponse,但它会将代码移动到具有许多/多种方法的单个对象,我认为反射会导致性能问题。
是否有一个很好的设计方法/模式来清理它?
答案 0 :(得分:6)
两种方法:
例如:
将它放在构造函数
中 responses = new HashMap<string, SomeAbstraction>();
responses.Put(CLIENT_REGISTERED, new ImplementationForRegisteredClient());
responses.Put(CLIENT_ABORTED, new ImplementationForAbortedClient());
其中ImplementationForRegisteredClient
和ImplementationForAbortedClient
实施SomeAbstraction
并通过此字典调用
responses.get(responseType).MethodOfYourAbstraction(SomeParams);
如果您想遵循DI的原则,可以在您的客户端类中注入此Dictionary。
答案 1 :(得分:2)
我的第一个切割是用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...
}
从那里我可能会提取每个块作为一种方法,并从那里应用策略模式。在任何感觉正确的地方停下来。
答案 2 :(得分:0)
您描述的案例似乎完全适合策略模式的应用。特别是,您有许多算法变体,即根据远程服务器调用的响应执行的代码。
实现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方法模式。
您需要 factory 才能在运行时创建特定策略。工厂将根据收到的回复制定战略。可能的实现应该是@Sattar Imamov建议的实现。工厂将包含if .. else
代码。
如果策略类的构建时间不重,并且在构建时不需要任何外部信息,您也可以将每个策略映射到枚举值。
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;
}
}