Дизайн для слоя перевода
Я пытаюсь спроектировать один сервер переводов. Там есть один класс POJO (RootClass
) в моих локальных системах. и там также есть удаленная система для отправки удаленного объекта (RemoteClass
) к моей системе. Обязанностью этого сервиса является перевод удаленного класса в корневой. Проблема в том, что там так много типов. например, более 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-класс - это ядро нашей системы, и его невозможно выставить напоказ, и мы также думаем, что этот Root-класс очень подходит для локальной системы. и для удаленного класса - от сторонних систем, которые мы не имеем права изменять. Так что этот перевод стал очень сложным.
Что я планирую удалить, так это создать более 200 усыновителей для перевода: например:
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 небольших классов, чтобы обернуть, если / еще, Есть ли хороший шаблон или дизайн, чтобы решить эту сложную проблему? Заранее спасибо.
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);
}