В этом коде есть что-то очень неудовлетворительное:
/*
Given a command string in which the first 8 characters are the command name
padded on the right with whitespace, construct the appropriate kind of
Command object.
*/
public class CommandFactory {
public Command getCommand(String cmd) {
cmdName = cmd.subString(0,8).trim();
if(cmdName.equals("START")) {
return new StartCommand(cmd);
}
if(cmdName.equals("END")) {
return new EndCommand(cmd);
}
// ... more commands in more if blocks here
// else it's a bad command.
return new InvalidCommand(cmd);
}
}
Я не раскаялся по поводу нескольких точек выхода - структура ясна. Но я не доволен серией почти идентичных утверждений. Я рассмотрел создание карты строк для команд:
commandMap = new HashMap();
commandMap.put("START",StartCommand.class);
// ... etc.
... затем с помощью Reflection сделать экземпляры соответствующего класса оторванными от карты. Однако, хотя концептуально элегантно, это включает в себя значительное количество кода Reflection, который тот, кто наследует этот код, может не оценить - хотя эта стоимость может быть компенсирована преимуществами. Все строки, жестко кодирующие значения в commandMap, пахнут почти так же плохо, как блок if.
Еще лучше было бы, если бы конструктор фабрики мог сканировать путь к классам для подклассов Command, запрашивать их для представлений String и автоматически добавлять их в свой репертуар.
Итак - как мне провести рефакторинг этого?
Я предполагаю, что некоторые из этих платформ дают мне такие вещи бесплатно. Давайте предположим, что я не в состоянии перенести этот материал в такую среду.