这个主意

我需要创建命令。可以使用参数配置命令。
并非每个命令都可以接收相同的参数。因此,一些必须被忽略。

我有一个抽象类Command,其中定义了一个Builder。默认情况下,每个附加参数都抛出“UnsupportedOperationException”

public abstract class Command {

   public static abstract class CommandBuilder {

        // TODO instanceof. How to do this better?
        public CommandBuilder append(Parameter p)
            throws UnsupportedOperationException {

            if (p instanceof URLParameter)
                return append((URLParameter) p);

            if (p instanceof ActionParameter)
                return append((ActionParameter) p);

            if (p instanceof RepeatParameter)
                return append((RepeatParameter) p);

            if (p instanceof TimeOutParameter)
                return append((TimeOutParameter) p);

            return this;

        }

        public CommandBuilder append(URLParameter p)
                throws UnsupportedOperationException {

                    throw new UnsupportedOperationException(
                        "URLParameter not applicable");

        }

        public CommandBuilder append(RepeatParameter p)
            throws UnsupportedOperationException {

                throw new UnsupportedOperationException(
                    "RepeatParameter not applicable");

            }
            ...

}

如果您希望参数适用于某个特定的Command,那么可以说FTPCommand。

您将必须执行以下操作:
public class FTPCommand extends Command {

    public static class Builder extends CommandBuilder {

    @Override
    public CommandBuilder append(URLParameter p) {
            System.out.println("URLParemeter appended");
                return this;
            }
        }

}

这样,当提供URLParameter时,它不再抛出异常,而是应用它。

但是此CommandBuilder的客户端可能无法提供具体的子类。因此,通常会给出一个“参数”。但是它需要去正确的地方(方法)

像URLParameter必须到达append(UrlParameter p)
我该如何以一种简洁的方式来做到这一点?因为我并不是真的很“热情”地使用instanceof。

最佳答案

这看起来像经典的double-dispatchvisitor方案。从双调度参考:

一种将函数调用分派给不同具体对象的机制
函数的功能取决于所涉及的两个对象的运行时类型
电话
ParameterCommandBuilder需要在彼此之间进行交互。
CommandBuilder可以回调该参数。 Parameter对象均实现一个公共接口,每个子类的实现将有所不同。

public CommandBuilder append(Parameter p) {
   // the append method called depends on the underlying type of 'p'
   p.append(this);
}

08-04 19:44