如果您的命令是无状态的、线程安全的对象,您可以创建一个急切创建的实例的映射并重复使用这些实例:
public class CommandFactory {
private final Map<String, Command> availableCommands;
public CommandFactory(Map<String, Command> availableCommands) {
this.availableCommands = availableCommands;
}
public Command getCommand(String s) {
if (availableCommands.contains(s) {
return availableCommands.get(s);
} else {
// handle error state
}
}
}
为了这有任何好处(并满足“不更改类”的要求)但是工厂不会是一个静态类,具有实例(而不是静态)getCommand()
方法。然后可以使用 DI 框架注入可用的命令。
如果您需要为每个调用创建一个新的实现实例,那么如果不使用可怕的链Command
,您就无法真正避免反射。if...else if
不过,我不会太担心在这种情况下使用它,它的Class.newInstance()
可读性很强,而且效率也不是很低。
尽管如此,我仍然会坚持使用这种地图方法,以使其灵活且可通过配置进行扩展。代码将与 类似Map<String, Class>
,return availableCommands.get(s).newInstance()
以及更多的异常检查。
第三种可能的方法是为每个命令类型创建一个单独的工厂类,并Map<String, SpecificCommandFactory>
使用样板代码并且可能非常不可读,因此仅在您确实需要将工厂可用的命令分开时才适用:
public iterface SpecificCommandFactory {
Command createCommand();
}
public class Comm_AFactory implements SpecificCommandFactory {
public Comm_A createCommand() {
return new Comm_A();
}
}
public class CommandFactory {
private final Map<String, SpecificCommandFactory> availableCommands;
public CommandFactory(Map<String, Command> availableCommands) {
this.availableCommands = availableCommands;
}
public Command getCommand(String s) {
if (availableCommands.contains(s) {
return availableCommands.get(s).createCommand();
} else {
// handle error state
}
}
}