我尝试设计一个翻译服务器。
我的本地系统中有一个POJO类(RootClass
)。并且还有远程系统将远程对象(RemoteClass
)发送到我的系统。
此服务的职责是将Remote类转换为Root类。
问题是:有这么多类型。例如200多种类型。我需要写一些巨大的if-else来做这个翻译:
我列出了一些伪代码来描述这个问题。
public class RootClass {
public String type;
public String attr1;
public String attr2;
public String attr3;
public String attr4;
}
public class RemoteClass {
public String type;
public String attr1;
public String attr2;
public String attr3;
}
public class Translator{
public RootClass translate(RemoteClass remote) {
RootClass root = new RootClass();
if ("a".equals(remote.type )) {
root.type = "veryGood";
if ("one".equals(remote.attr1)) {
root.attr2 = "true";
}
if ("two".equals(remote.attr1)) {
root.attr3 = "true";
}
if ("1".equals(remote.attr1) && "2".equals(remote.attr2) ) {
root.attr4 ="good";
}
} else if ("b".equals(remote.type)) {
root.type = "good";
if ("one".equals(remote.attr1)) {
root.attr2 = "1";
} else if ("two".equals(remote.attr1)) {
root.attr2 ="2";
}
} else if ("c".equals(remote.type)) {
root.type = "good";
if (remote.attr2.indexOf(":") > 0 ) {
String[] strArray = remote.attr2.split(":");
root.attr2=strArray[0];
root.attr3=strArray[1];
}
}
}
}
2对象描述了具有完全不同结构的1件事。 根类是我们系统的内核,不可能支撑,我们也认为这个Root类非常适合本地系统。 Remote类来自第3方系统,我们无权更改。所以这种翻译变得非常困难。
我打算删除的是为翻译创建超过200个采用者: e.g:
public class adopterA implements RootAdoper {
public RootClass translate(RemoteClass remote) {
RootClass root = new RootClass();
root.type="veryGood";
if ("one".equals(remote.attr1)) {
root.attr2 = "true";
}
if ("two".equals(remote.attr1)) {
root.attr3 = "true";
}
if ("1".equals(remote.attr1) && "2".equals(remote.attr2) ) {
root.attr4 ="good";
}
}
}
并将所有这些放入HasMap
Map<String, RootAdoper> map = new HashMap<String, RootAdoper>();
但仍然有200个小类包装if / else,是否有任何好的模式或设计来解决这个复杂的问题?提前谢谢。
答案 0 :(得分:1)
地图中的关键是什么?如果密钥是Remote.type
那么你就可以做到
rootClass = map.get(remote.type).translate(remote);
哪个摆脱了if / else if块。请务必处理未知/未翻译的区域,或者使用不会翻译或执行默认翻译的NullObject
。
从 Refactoring to Patterns 一书中的技术名称称为“用命令替换条件调度程序”
你仍然需要填充地图。也许一种方法是使所有RootAdoper
接口成为枚举,所有实现都是枚举中的类型。您还可以向枚举添加新方法以获取每个值可以转换的Remote.Type。
enum RootAdoper{
A{
@Overide
public RootClass translate(RemoteClass remote){
//...
}
@Override
public String getTypeToTranslate(){
return "A";
}
},
... // other types listed here similarly
;
abstract RootClass translate(RemoteClass remote);
abstract String getTypeToTranslate();
}
然后你可以像这样填充地图
Map<String, RootAdoper> map = new HashMap<String, RootAdoper>();
for(RootAdoper adoper : RootAdoper.values(){
map.put(adoper.getTypeToTranslate(), adoper);
}