How to get rid of instanceof in this Builder implementation

Idea

I need to create teams. Commands can be configured with options. Not every team can receive the same parameters. Therefore, some should be ignored.

I have an abstract class command in which I defined Builder. By default, each append parameter throws a "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");

            }
            ...

}

If you want the parameter to be applicable to a specific command, say FTPCommand.

You will need to do something like this:

public class FTPCommand extends Command {

    public static class Builder extends CommandBuilder {

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

}

Thus, when a URL parameter is provided, it no longer throws an exception, but instead applies it.

CommandBuilder, , . "". ()

URL- append(UrlParameter p)

(er) (r) ? "", instanceof.

+5
2

visitor. :

, , ,

Parameter CommandBuilder , .

CommandBuilder . Parameter , .

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

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

class CommandBuilder {
    public CommandBuilder append(Parameter p) {
       p.append(this);
    }
}
+4

All Articles