【发布时间】:2014-01-31 21:52:15
【问题描述】:
我有一个对象层次结构,它随着继承树的加深而增加复杂性。这些都不是抽象的,因此,它们的所有实例都服务于一个或多或少复杂的目的。
由于参数的数量非常多,我想使用构建器模式来设置属性,而不是编写多个构造函数。由于我需要满足所有排列,我的继承树中的叶类将具有伸缩构造函数。
当我在设计过程中遇到一些问题时,我在这里浏览了答案。首先,我举一个简单浅薄的例子来说明问题。
public class Rabbit
{
public String sex;
public String name;
public Rabbit(Builder builder)
{
sex = builder.sex;
name = builder.name;
}
public static class Builder
{
protected String sex;
protected String name;
public Builder() { }
public Builder sex(String sex)
{
this.sex = sex;
return this;
}
public Builder name(String name)
{
this.name = name;
return this;
}
public Rabbit build()
{
return new Rabbit(this);
}
}
}
public class Lop extends Rabbit
{
public float earLength;
public String furColour;
public Lop(LopBuilder builder)
{
super(builder);
this.earLength = builder.earLength;
this.furColour = builder.furColour;
}
public static class LopBuilder extends Rabbit.Builder
{
protected float earLength;
protected String furColour;
public LopBuilder() { }
public Builder earLength(float length)
{
this.earLength = length;
return this;
}
public Builder furColour(String colour)
{
this.furColour = colour;
return this;
}
public Lop build()
{
return new Lop(this);
}
}
}
现在我们有一些代码要继续,成像我想构建一个Lop:
Lop lop = new Lop.LopBuilder().furColour("Gray").name("Rabbit").earLength(4.6f);
此调用将无法编译,因为无法解析最后一个链式调用,Builder 未定义方法 earLength。所以这种方式要求所有调用都以特定的顺序链接起来,这是非常不切实际的,尤其是对于深度层次树。
现在,在我寻找答案的过程中,我遇到了Subclassing a Java Builder class,它建议使用Curiously Recursive Generic Pattern。但是,由于我的层次结构不包含抽象类,因此此解决方案不适用于我。但是这种方法依赖于抽象和多态来发挥作用,这就是为什么我不相信我可以根据自己的需要调整它。
我目前采用的一种方法是覆盖层次结构中超类Builder 的所有方法,并简单地执行以下操作:
public ConcreteBuilder someOverridenMethod(Object someParameter)
{
super(someParameter);
return this;
}
通过这种方法,我可以确保返回一个可以发出链调用的实例。虽然这没有伸缩反模式那么糟糕,但它紧随其后,我认为它有点“hacky”。
是否有其他我不知道的问题的解决方案?最好是符合设计模式的解决方案。谢谢!
【问题讨论】:
-
您链接到的 SO 问题确切地告诉您如何执行此操作,并且答案中没有任何地方涉及抽象类。
-
我已经阅读了上述问题,甚至在我的问题中提到了它。正如我所说,由于几个缺点,这个问题没有提供答案。该答案不涉及抽象类,因为它错误地应用了模式。
标签: java design-patterns inheritance builder