このコードには非常に不満な点があります:
/*
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);
}
}
私は複数の出口点について後悔していません - 構造は明らかです。しかし、ほぼ同一の一連の if ステートメントには満足できません。文字列からコマンドへのマップを作成することを検討しました:
commandMap = new HashMap();
commandMap.put("START",StartCommand.class);
// ... etc.
...次に、リフレクションを使用して、マップからルックアップされた適切なクラスのインスタンスを作成します。ただし、概念的には洗練されていますが、これにはかなりの量の Reflection コードが含まれており、このコードを継承する人は誰でも理解できない可能性があります。ただし、そのコストは利点によって相殺される可能性があります。commandMap に値をハードコーディングするすべての行は、if ブロックとほぼ同じくらい悪臭を放ちます。
ファクトリのコンストラクターが Command のサブクラスのクラスパスをスキャンし、それらに文字列表現を照会し、それらをレパートリーに自動的に追加できれば、さらに良いでしょう。
では、これをリファクタリングするにはどうすればよいですか?
そこにあるフレームワークの中には、この種のものを無料で提供してくれるものがあると思います。私がこのようなものをそのようなフレームワークに移行する立場にないと仮定しましょう。