1

我有建设者:

public abstract class ScriptBuilder {
    public void buildScript() {
        this.commandList = Lists.newArrayList();
    }
    public abstract void buildSleepCommand(long time);
    public abstract void buildSynchronizationCommand();
    public abstract void buildTouchDownCommand(TouchPoint touchPoint);
    public abstract void buildTouchUpCommand();
    public List<String> getScript() {
        return commandList;
    }
}

执行:

public class StandardScriptBuilder extends ScriptBuilder{
…
}

我需要构建一个新的构建器,它实现了新的接口。这个新接口基于接口 ScriptBuilder:

class NewScriptBuilder extends StandardScriptBuilder{
    public void buildNewCommand(TouchPoint startTouchPoint, TouchPoint endTouchPoint) {
        buildTouchDownCommand(startTouchPoint);
        buildSynchronizationCommand();
        buildTouchDownCommand(endTouchPoint);
    }
    …
}

是否有任何模式可以扩展现有的构建器界面并保持构建器的优势?我的意思是,如果我们扩展接口,我们不能这样做:

ScriptBuilder builder = new NewScriptBuilder();
…
builder.buildNewCommand;

如果没有解决办法,正常使用吗?:

((NewScriptBuilder)builder).buildNewCommand;

谢谢。


我的意思是:例如,我们可以使用装饰器模式:

public abstract class Decorator extends ScriptBuilder {...} ...

public class OahDecorator extends Decorator {
...
    public void buildNewCommand() {
    ...
    }
}

是正常组织代码,还是选择不同的模式是?任务 - 在构建器中添加新方法。

4

3 回答 3

1

如果你想让一个类实现多个行为,你应该让它实现多个接口。对类进行编码通常是不好的做法——你应该对接口进行编码。差异是微妙的,但仍然非常相关和真实。

当您发现自己显式转换时,通常意味着您的接口不太适合该任务。目标是让客户端代码尽可能少地了解它正在处理的对象的实际类型。

于 2012-07-09T06:27:43.953 回答
0

使用接口的想法是您不关心实现类型是什么,也不需要子类上的特定方法。如果确实需要调用子类特定的方法,则需要像上面所做的那样向下转换。

于 2012-07-08T17:54:14.007 回答
0

您要调用的事实builder.buildNewCommand()意味着您已经知道它是 type NewScriptBuilder。为什么不直接声明它NewScriptBuilder呢?

NewScriptBuilder builder = new NewScriptBuilder();
...
builder.buildNewCommand();

如果这是不可能的(也许您正在使用外部 API?),那么您可以包装ScriptBuilder而不是扩展它:

public class NewScriptBuilder {
  private final ScriptBuilder builder;

  public NewScriptBuilder(ScriptBuilder builder) {
    this.builder = builder;
  }

  public void buildNewCommand(TouchPoint startTouchPoint, TouchPoint endTouchPoint) {
    builder.buildTouchDownCommand(startTouchPoint);
    builder.buildSynchronizationCommand();
    builder.buildTouchDownCommand(endTouchPoint);
  }
}

并在您想使用时创建一个新实例buildNewCommand

ScriptBuilder builder = ...;
NewScriptBuilder newBuilder = new NewScriptBuilder(builder);
newBuilder.buildNewCommand();
于 2012-07-09T07:50:59.127 回答