我有建设者:
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() {
...
}
}
它是一个正常的代码组织,还是选择不同的模式呢? 任务 - 在构建器中添加新方法。
答案 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();