如何摆脱这个Builder实现中的instanceof [英] How to get rid of instanceof in this Builder implementation

查看:134
本文介绍了如何摆脱这个Builder实现中的instanceof的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to create Commands. Commands can be configured with parameters. Not every command can receive the same parameters. So some have to be ignored.

我有一个抽象类命令,其中我定义了一个Builder。默认情况下,每个append参数都会抛出'UnsupportedOperationException'

I have an abstract class Command in which I've defined a Builder. By default every append parameter throws '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。

If you want a parameter to be applicable onto a certain concrete Command, lets say an 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时,它不会抛出异常,而是应用它。

So that when a URLParameter is provided it doesn't throw an exception anymore but instead applies it.

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

But the client of this CommandBuilder might not be able to provide the concrete subclass. So in general a "Parameter" is given. But it needs to go to the right place (method)

像URLParameter一样,必须到达 append(UrlParameter p)

Like a URLParameter must arrive at the append(UrlParameter p)

如何以干净(呃)和漂亮(r)的方式这样做?因为我不是真的'enthusiastic'使用instanceof。

How can I do this in a clean(er) and nice(r) way? Because I'm not really 'enthousiastic' to use instanceof .

推荐答案

这看起来像一个经典的双重派驻访客场景。从双调度引用:

This looks like a classic double-dispatch or visitor scenario. From the double-dispatch reference:


根据运行时类型调用函数调用不同的具体
函数的机制
中涉及的两个对象调用

a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call

参数 CommandBuilder 需要在自己之间进行交互。

The Parameter and the CommandBuilder need to interact between themselves on what to do.

CommandBuilder 可以回调参数。 参数对象都实现一个公共接口,每个子类的实现将不同。

The CommandBuilder can call back on the parameter. The Parameter objects all implement a common interface and the implementation of each subclass will differ.

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

这篇关于如何摆脱这个Builder实现中的instanceof的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆