java 命令模式与反射

gzszwxb4  于 2022-12-21  发布在  Java
关注(0)|答案(4)|浏览(141)

我有一个控制器,它根据命令名执行一些命令,从url中获取。主要的一点是不要使用if和switch子句。据我所知,只有两种方法可以做到这一点- 1)命令模式2)反射。

//Command pattern
class Controller{
  private HashMap<String,Command> commands;
  public void executeCommand(String commandName){
    commands.get(commandName).execute();
  }
  ...
}

//reflection
class Controller{
  public void readCommand(){
    ....
  }
  public void executeCommand(String commandName){
    this.getClass().getMethod(commandName+"Command").invoke(this);
  }
  ...
}

所以问题是:
1.哪一个比较好?
1.在一个应用程序中让开发人员使用他们想要的方法之一是正常的吗?
1.还有别的办法吗?

ax6ht2ek

ax6ht2ek1#

1.第一种方法更好,只有在没有其他选择时才使用反射。
1.在一种应用中,应该有一种方法来解决一种问题。
1.我认为第一种方法是好的。(比if/else块好得多)

np8igboo

np8igboo2#

哪一个比较好?
显然第一个更好。即使你引用了你正在使用的命令模式,它不是完整的"命令"模式。* 命令模式将有命令(抽象),具体命令,接收器,调用器和客户端 *。
看看这个问题:
使用命令设计模式
除了Command Patten之外,我还想强调一下反射的优点和缺点。

优点:

1.处理依赖项注入
1.开发即插即用框架

*缺点

1.反射调用较慢
1.您可能会恶意破坏安全性和扩展应用程序(例如,设置一个类的私有变量,这对其他类是不可见的)
查看与反思相关的SE问题:
What is reflection and why is it useful?
在一个应用程序中让开发人员使用他们想要的方法之一是正常的吗?
开发人员选择最好的方法来解决特定的问题是很正常的。
还有别的办法吗?
这取决于你要解决的问题的类型。设计模式为重复出现的问题提供了解决方案。
所有的解决方案都不适合现有的设计模式。您可能已经开发了新的模式来解决您的问题。

fslejnso

fslejnso3#

我认为第一种方法有两种不同的方式。每个命令都可以是抽象类Command的子类。或者每个命令都可以是类Command的示例。这取决于所有这些应该有多灵活,以及命令的参数和返回值是什么?对于子类,它看起来像这样(只是为了理解这个概念):

abstract public class Command {
    abstract public void execute();
}

public class LsCommand extends Command
{
    @Override
    public void execute() {
        try {
            Runtime.getRuntime().exec("ls");
        } catch (IOException e) {}
    }
}

public class ChdirCommand extends Command
{
    @Override
    public void execute() {
        try {
            Runtime.getRuntime().exec("chdir");
        } catch (IOException e) {}
    }
}

这里我的答案:
1.你的第一种方法更好,总是喜欢设计模式而不是反射。
1.对不起,我不明白问题2。但它没有一个问号反正,所以我只是跳过它:)
1.你可能想看看Strategy design pattern,其中每个命令甚至可以由子命令的不同部分组成。另一个想法是Factory design pattern。在这种情况下,你可以将每个命令放入一个类中,然后使用ClassLoader按名称加载类。

1l5u6lss

1l5u6lss4#

这不是一个对另一个的明显区别,你可以两者兼得:

public class Controller {
     public void executeCommand(String commandName){
          CommandFactory.getCommand(commandName).execute();
      }         
} 
public class CommandFactory {

private static final String COMMAND_PACKAGE = "come.example.command.";

private static Map<String, Command> commandMap = new HashMap<>();

public static Command getCommand (String commandName){
    if (commandMap.containsKey(commandName)){
        return commandMap.get(commandName);
    }
    String commandNameCapitalized = commandName.substring(0, 1).toUpperCase() + commandName.substring(1);
    String commandClassString = COMMAND_PACKAGE + commandNameCapitalized;
    try {
        Class commandClass = Class.forName(commandClassString);
        Command command = (Command) commandClass.newInstance();
        commandMap.put(commandName, command);
        return command;
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
   }

}

相关问题