5

这个想法

我需要创建命令。命令可以配置参数。并非每个命令都可以接收相同的参数。所以有些不得不被忽略。

我有一个抽象类命令,我在其中定义了一个生成器。默认情况下,每个附加参数都会抛出“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");

            }
            ...

}

如果您希望参数适用于某个具体命令,可以说是 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)

我怎样才能以干净(er)和漂亮(r)的方式做到这一点?因为我对使用 instanceof 并不是很“热情”。

4

2 回答 2

7

这看起来像一个经典的双重调度访客场景。从双重调度参考:

一种机制,根据调用中涉及的两个对象的运行时类型将函数调用分派到不同的具体函数

并且需要在他们之间就做什么进行交互ParameterCommandBuilder

CommandBuilder可以回调参数。这些Parameter对象都实现了一个公共接口,每个子类的实现会有所不同。

public CommandBuilder append(Parameter p) {
   // the append method called depends on the underlying type of 'p'
   p.append(this);
}
于 2012-08-03T09:32:02.150 回答
4

我会在您的界面中添加一个访问者方法

interface Parameter {
    public void append(CommandBuilder builder);
}

class CommandBuilder {
    public CommandBuilder append(Parameter p) {
       p.append(this);
    }
}
于 2012-08-03T09:36:23.787 回答