我有一个对象层次结构,随着继承树的加深而变得越来越复杂。它们都不是抽象的,因此它们的所有实例都具有更或多或少复杂的目的。
由于参数数量相当高,我想使用建造者模式来设置属性,而不是编写几个构造函数。由于我需要考虑所有排列组合,所以继承树中的叶子类将具有伸缩构造函数。
在我的设计过程中遇到问题时,我在这里浏览了一些答案。首先,让我给你举一个简单的、浅显的例子来说明问题。
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;
}
通过这种方法,我可以确保返回一个实例,我可以在其上发出链式调用。虽然这不像 Telescoping Anti-pattern 那样糟糕,但它是一个接近第二的模式,我认为它有点“hacky”。
是否有另一种解决我的问题的方法,我不知道吗?最好是与设计模式一致的解决方案。谢谢!