多态对象层次结构的构建器模式:可能用Java? [英] Builder pattern for polymorphic object hierarchy: possible with Java?
问题描述
我有一个接口层次结构, Child
实现 Parent
。我想使用不可变对象,所以我想设计一个方便地构建这些对象的 Builder
类。但是,我有很多 Child
接口,我不想重复每个代码来构建 Parent
I have a hierarchy of interfaces, with Child
implementing Parent
. I would like to work with immutable objects, so I would like to design Builder
classes that construct these objects conveniently. However, I have many Child
interfaces, and I don't want to repeat the code for building Parent
s in each type of child builder.
所以,假设以下定义:
public interface Parent {
public Long getParentProperty();
}
public interface Child1 extends Parent {
public Integer getChild1Property();
}
public interface Child2 extends Parent {
public String getChild2PropertyA();
public Object getChild2PropertyB();
}
如何有效地实施构建器 Child1Builder
和 Child2Builder
?他们应该支持如下操作:
How can I efficiently implement builders Child1Builder
and Child2Builder
? They should support operation like:
Child1 child1 = Child1Builder.newChild1().withChild1Property(5).withParentProperty(10L);
和
Child2 child2 = Child2Builder.newChild2().withChild2PropertyA("Hello").withParentProperty(10L).withChild2PropertyB(new Object());
我不想使用ParentProperty $实现一个特殊情况 c $ c>为每个小孩建造者。
I don't want to implement a special case of withParentProperty
for each child builder.
编辑添加第二个属性到 Child2
,以澄清这不可能用简单的泛型完成我不是在寻找一种方法来组合 Child1
和 Child2
- 我正在寻找一种实现 Builder
系统不重复为每个子类构建父类的工作。
Edited to add second property to Child2
to clarify that this cannot be done with simple generics. I am not looking for a way to combine Child1
and Child2
- I am looking for a way to implement a Builder
system that does not duplicate the work of building the parent class for every child class.
感谢任何帮助! / p>
Thanks for any help!
推荐答案
我想象的解决方案就像 好奇地循环模板模式 或 CRTP 。您可以定义一个基类来处理与父相关的初始化,但是您仍然可以找到两个样板 getParent()
和 getThis()
方法在每个派生的与孩子相关的构建器类中重复太多。
The solution I imagine is like the Curiously Recurring Template Pattern, or CRTP. You can define a base class to handle the parent-related initialization, but you still may find the two boilerplate getParent()
and getThis()
methods to be too much repetition in each derived child-related builder class.
查看:
abstract class ParentBase implements Parent
{
@Override
public final Long getParentProperty()
{
return parentProperty_;
}
protected void setParentProperty(Long value)
{
parentProperty_ = value;
}
private Long parentProperty_;
}
abstract class ParentBuilder<T extends ParentBuilder<T>>
{
T withParentProperty(Long value)
{
getParent().setParentProperty(value);
return getThis();
}
protected abstract ParentBase getParent();
protected abstract T getThis();
}
final class ConcreteChild1 extends ParentBase implements Child1
{
@Override
public Integer getChild1Property()
{
return childProperty_;
}
public void setChild1Property(Integer value)
{
childProperty_ = value;
}
private Integer childProperty_;
}
final class Child1Builder extends ParentBuilder<Child1Builder>
{
public Child1Builder()
{
pending_ = new ConcreteChild1();
}
public Child1Builder withChild1Property(Integer value)
{
pending_.setChild1Property(value);
return this;
}
@Override
protected ParentBase getParent()
{
return pending_;
}
@Override
protected Child1Builder getThis()
{
return this;
}
private final ConcreteChild1 pending_;
}
如您所见, ParentBuilder
type期望与派生类型协作,以允许它返回一个正确类型的实例。自己的这个
引用将不会到期,因为 c
当然是 ParentBuilder
,而不是说, Child1Builder
旨在维护流利的通话链接。
As you can see, the ParentBuilder
type expects to be cooperating with a derived type to allow it to return a properly-typed instance. Its own this
reference won't due, because the type of this
within ParentBuilder
is, of course, ParentBuilder
, and not, say, Child1Builder
as intended to maintain the "fluent" call chaining.
我欠 getThis()
技巧到安格丽卡兰格的教程条目。
这篇关于多态对象层次结构的构建器模式:可能用Java?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!