当前位置: 首页 > 面试题库 >

多态对象层次结构的构建器模式:可以在Java中使用吗?

姜乐语
2023-03-14
问题内容

我具有Child实现的接口层次结构Parent。我想使用不可变的对象,所以我想设计一些Builder类来方便地构造这些对象。但是,我有很多Child接口,并且我不想Parent在每种类型的子生成器中重复构建s
代码

因此,假设以下定义:

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?他们应支持以下操作:

Child1 child1 = Child1Builder.newChild1().withChild1Property(5).withParentProperty(10L);

Child2 child2 = Child2Builder.newChild2().withChild2PropertyA("Hello").withParentProperty(10L).withChild2PropertyB(new Object());

我不想withParentProperty为每个子生成器实现一个特殊情况。

编辑以添加第二个属性,Child2以澄清使用简单的泛型无法做到这一点。我不是在寻找一种方式来组合Child1Child2-我正在寻找一种方式来实现Builder,不重复建设的父类为每个子类的工作体系。

谢谢你的帮助!


问题答案:

我想象的解决方案就像是
好奇地重复使用的模板模式

CRTP
。您可以定义一个基类来处理与父相关的初始化,但是您仍然可能会发现两个样板getParent()getThis()方法在每个派生的与子相关的构建器类中重复太多。

看一看:

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参考不会到期,因为类型this之内ParentBuilder,当然,ParentBuilder而不是,比方说,Child1Builder如预期维持“流利”的呼叫链接。

我欠了“
getThis()帽子戏法”,以安格朗格的入门教程。



 类似资料:
  • 问题内容: 在“深度”对象层次结构中使用Builder模式的最佳实践是什么?详细地说,我探讨了将Joshua Bloch提出的Builder模式应用于我的XML绑定代码的想法(我使用的是SimpleXML,但是这个问题将适用于任何情况)。我的对象层次结构深达4个级别,具有不同程度的复杂性。我的意思是,在某些级别上,我的对象只有几个属性,而在其他级别上,我最多可以有10个属性。 因此,请考虑以下假设

  • 零售商店的正确模式是什么?公司从商店销售产品。 这似乎违反了我对OOP所知的全部知识。通过层次结构向下传递数据的方法--在对象之间复制参数?我错过了什么?

  • 在Tableau中,可以构建层次结构以可视化数据。可以通过以下步骤在Tableau中创建它: 例如,考虑数据源,例如Sample-Superstore,以及它的维度和度量。 第1步: 首先转到工作表。然后, 选择一个维度,然后右键单击该维度以创建层次结构。 转到“层次结构(Hierarchy)”选项。 并且,单击下面屏幕截图中显示的“创建层次结构(Create Hierarchy)”选项。 第2步

  • 问题内容: 我正在重新编写一些代码,并且已经确定了重新创建类的方式,因为存在固定数量的工作表,所以我将它们创建为枚举。这是基于构建器模式与伸缩构建器的可读性来做出的决定。 我获取的代码抓取了一些.xls文件,添加了标头(并从其他.xls文件中读取了一些标头),甚至还有一些子表。然后,它以特定方式将各种工作表合并在一起,以在主要excel工作簿上制作选项卡。我的问题是某些工作簿选项卡采用不同数量的工

  • 问题内容: 我在 .NET for WinRT(C#)中 ,我想将JSON字符串反序列化为,然后将字典值稍后转换为实际类型。JSON字符串可以包含对象层次结构,我也希望在其中包含子对象。 这是应该能够处理的示例JSON: 我尝试使用 DataContractJsonSerializer 这样做: 实际上,这对于第一个级别是可行的,但是 “父母” 只是一个不能强制转换为的对象: 然后,我尝试使用 J

  • 这可能是一个非常奇怪的问题,但我甚至不知道如何命名这个问题。我对C#和Selenium很陌生。我已经对它做了一些编码,我很乐意创建一个(quitemessy)测试,它可以按照我想要的方式运行。我想把我的考试安排得更好一点。 我将用这个例子来说明我想要实现的目标: 在登录页面上,我们可以说我有一个“登录”按钮,该按钮打开一个页面,让我输入我的凭证“用户名”和“密码”。 让我们说我想这样编程:有登录的