多态对象层次结构的构建器模式:Java 可能吗? [英] Builder pattern for polymorphic object hierarchy: possible with Java?

查看:11
本文介绍了多态对象层次结构的构建器模式: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 Parents 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();
}

如何有效地实现构建器 Child1BuilderChild2Builder?他们应该支持如下操作:

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());

我不想为每个子构建器实现 withParentProperty 的特殊情况.

I don't want to implement a special case of withParentProperty for each child builder.

编辑为 Child2 添加第二个属性,以阐明这不能通过简单的泛型来完成.我不是在寻找一种结合 Child1Child2 的方法 - 我正在寻找一种方法来实现一个不重复的 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.

感谢您的帮助!

推荐答案

我想象的解决方案就像 Curiously Recurring Template模式,或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 类型期望与派生类型合作以允许它返回正确类型的实例.它自己的this 引用不会到期,因为ParentBuilderthis 的类型当然是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() 技巧"归功于 Angelika Langer 的教程入口.

I owe the "getThis() trick" to Angelika Langer's tutorial entry.

这篇关于多态对象层次结构的构建器模式:Java 可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆