生成器模式。扩展界面

时间:2012-07-08 17:49:54

标签: java design-patterns builder

我有建设者:

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;

THX。


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

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

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

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

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您要致电builder.buildNewCommand()这一事实意味着您已经知道它属于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();