1

这是关于如何在此 Builder 实现中摆脱 instanceof的后续线程

这种设计仍然存在一些问题。每次引入新参数时,都必须创建一个新的 ConcereteParameter 类。

这不是问题。但是还必须在 CommandBuilder 中添加方法append(ConcreteParameter)。而且我不太喜欢这种依赖。

总结

  • 命令可以配置参数。并非每个命令都可以接收相同的参数。所以有些不得不被忽略。当应用于命令时(在这个实现中,这是通过抛出一个UnsupportedOperationException

  • 可以应用于某些类的参数在这些类中的使用方式不同(如 FTPCommand 和 HTTPCommand 可能以不同的方式使用 IpParameter)

  • 将来可能会引入新的命令和参数

更新 现在的实现works。但是,如果我有大约 30 个参数,那么对于每个参数我都必须有一个单独的方法,这不是矫枉过正吗?

如果有,实现这一目标的更干净、更灵活的方式/模式是什么?

4

2 回答 2

1

什么是你的参数,什么是参数类型?如果你真的有不同种类的对象作为参数,你可以对它们执行不同的操作,那么你就无法避免使用不同的类来处理它们。如果您的参数仅在命令解释它们的方式上有所不同,而其他主要是StringInteger或其他,那么为每种可能的含义设置额外的类肯定是​​矫枉过正。如果您的参数是某种形式的键值对,那么我会这样表示它们:一个包含参数名称和值的类(或者每个合理的值类型可能一个类)。

如果您可以使用上述方法来减少参数类型的数量,您可能需要考虑使用反射来构建实际的命令。您可以有一个注释@Parameter,用于装饰命令类的 setter 方法。例如@Parameter void setIP(String),这意味着该命令接受一个字符串参数,并将其解释为 IP 地址。如果您使用键值参数,则可以从方法名称派生键,或向注释添加值,或两者兼而有之。使用这样的框架,您可以拥有一个命令构建器,它负责将参数提供给适当的设置器。

于 2012-08-03T11:07:37.213 回答
0

即使有一个公认的答案,我觉得你需要知道另一种选择。

我会使用 aMap作为上下文对象,并将上下文传递给execute命令的方法。该命令将简单地从Mapby String 中提取它需要的参数。

public interface Command {
   public void execute(Map<String, Object> context);
}

class OneCommandImpl extends Command {
    public void execute(Map<String, Object> context) {
        context.get('p1');
        context.get('p2');
    }
}

这种方法的优点是简单,不需要反射。您可以使用这个接口构建任何需要任意数量参数的命令。主要缺点是 Map 中的值类型不具体。

于 2012-08-03T12:58:17.087 回答