Что-то очень неудовлетворительное в отношении этого кода:
/*
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 a bad command.
return new InvalidCommand(cmd);
}
}
Я не расчитываю на несколько точек выхода - структура ясна. Но я не доволен серией почти идентичных утверждений if. Я рассмотрел возможность создания карты строк для команд:
commandMap = new HashMap();
commandMap.put("START",StartCommand.class);
// ... etc.
... затем с помощью Reflection, чтобы отобразить экземпляры соответствующего класса с карты. Однако, хотя концептуально изящный, это включает в себя довольно много кода отражения, что тот, кто наследует этот код, может не оценить - хотя эта стоимость может быть компенсирована преимуществами. Все значения hardcoding строк в запасе commandMap почти так же плохи, как и блок if.
Еще лучше было бы, если конструктор factory мог бы сканировать путь к классам для подклассов Command, запрашивать их для представления String и автоматически добавлять их в свой репертуар.
Итак - как мне пойти на рефакторинг?
Я думаю, что некоторые из фреймворков дают мне такие вещи бесплатно. Предположим, что я не в состоянии перенести этот материал в такую структуру.