【问题标题】:Command pattern vs reflection命令模式与反射
【发布时间】:2015-01-19 06:25:43
【问题描述】:

我有控制器根据命令名称执行一些命令,取自 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. 哪个更好?
  2. 在一个应用程序中让开发人员使用他们想要的一种方法是否正常。
  3. 还有其他方法吗?

【问题讨论】:

  • 如果用户输入execute会发生什么?这会导致executeCommand 尝试递归调用自己吗?以这种方式使用反射,使用用户输入的字符串来确定要执行的方法名称,看起来非常很危险。不妨在你的程序上贴上一个标语,上面写着“嘿,网络犯罪分子!就是这样!!!”
  • @ajb 感谢您的评论。我知道,这就是为什么我们通过 xml 使用 url 映射器(url -> 组件,命令)。我写了“取自 url”来传递这个想法。

标签: java design-patterns reflection command-pattern


【解决方案1】:
  1. 第一种方法更好,只有在没有其他选项时才使用反射。
  2. 在一个应用程序中应该有一种方法来解决一种问题。
  3. 我认为第一种方法很好。 (比 if/else 块好得多)

【讨论】:

    【解决方案2】:

    哪个更好?

    显然第一个更好。即使您引用了您正在使用命令模式,它也不是完整的“命令”模式。 命令模式将有命令(抽象)、具体命令、接收者、调用者和客户端

    看看这个问题:

    Using Command Design pattern

    除了 Command Patten,我想强调反思的利弊。

    优点:

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

    缺点:

    1. 反射调用速度较慢
    2. 您可以违反安全性并以恶意破坏应用程序(例如,设置一个类的私有变量,其他类不可见)

    查看有关反射的相关 SE 问题:

    What is reflection and why is it useful?

    在一个应用程序中让开发人员使用他们想要的方法之一是否正常。

    开发人员选择最佳方法来解决特定问题是正常的。

    还有其他方法吗?

    这取决于您要解决的问题类型。设计模式为重复出现的问题提供了解决方案。

    所有解决方案都不适合现有的设计模式。您可能已经开发出新的模式来解决您的问题。

    【讨论】:

      【解决方案3】:

      我认为您的第一种方法有两种不同的方法。每个命令都可以是抽象类 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. 您的第一种方法更好。总是更喜欢设计模式 反思。
      2. 对不起,我没看懂问题 2。但它没有问号,所以我跳过它:)
      3. 您可能想查看Strategy design pattern,其中每个命令甚至可以由子命令的不同部分组成。 另一个想法是Factory design pattern。在这种情况下,你 将每个命令放入一个类中,然后使用 ClassLoader 按名称加载类。

      【讨论】:

      • 感谢您的回答。我想你有点误解了这个问题。命令模式是关于如何通过字符串动态选择必要的方法。例如字符串 "aaa" - method1(),"bbb" - method2() 不使用 if 和开关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 2017-01-08
      • 2012-02-15
      相关资源
      最近更新 更多