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

Java Builder模式和“深层”对象层次结构

仰欣悦
2023-03-14
问题内容

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

因此,请考虑以下假设示例(为简便起见,我省略了简单XML注释)

public class Outermost {

    private String title;
    private int channel;
    private List<Middle> middleList;

}

class Middle{
    private int id;
    private String name;
    private boolean senior;
    /* ... ... 10 such properties */

    private Innermost inner;
}

class Innermost{
    private String something;
    private int foo;
    /* ... Few more of these ..*/
}

如果我想Outermost使用构建器来强制创建对象,那么最好的方法是什么?最明显的答案是为inner static Builder上述每个类提供一个类。

但是,这会不会像Builder模式试图解决的那样使事情变得笨拙?我正在考虑类似的东西-这将强制实施“由内而外”的方法-
意味着在将Innermost对象添加到Middle对象之前,必须对其进行完全构造和实例化。但是我们都知道在实践中(尤其是在构建XML或JSON时),我们很少有“及时”的信息来完成此任务。

最终,每个级别的每个属性都将具有变量的机会;并在最后创建对象。否则,最终将使代码的多个级别的Builder浮动,从而增加了混乱。

那么,关于如何优雅地实现这一目标的任何想法?


问题答案:

我在这里对构建器模式的描述是您所指的;它与Wikipedia
此处描述的模式略有不同。我更喜欢前者。

我没有看到您对构造顺序或封装丢失的担心不可避免地遵循了我所阅读的描述。对我来说,最大的问题是原始数据的结构。

假设我们有

 public OuterBuilder {
     // some outer attributes here

     private ArrayList<MiddleBuilder> m_middleList;

     public OuterBuild( mandatory params for Outers ){
          // populate some outer attributes
          // create empty middle array
     }

     public addMiddle(MiddleBuilder middler) {
              m_middleList.add(middler);
     } 
 }

现在我们可以根据需要创建任意数量的middleBuilder

 while (middleDataIter.hasNext() ) {
      MiddleData data = middleDateIter.next();
      // make a middle builder, add it.
 }

我们可以将相同的模式应用于进一步的嵌套层次。

为了解决您的第一点,每个属性都有一个变量:取决于我们如何设计构建器以及数据来自何处。如果说,是从一个UI来的,那么每个属性几乎都有一个变量,那么我们的情况也不会更糟。如果按照我上面的建议,我们正在迭代某些数据结构,那么构建器可能会负责迭代该数据结构。在我的示例中,我们向下传递MiddleData实例。一些额外的耦合,但它确实封装了细节。

为了解决您的第二点,我们不会随便构建东西,而是有效地使用构建器作为数据的累积点。最终,我们调用了“ Go and
Build”方法,但是到那时我们应该将所有数据都放在适当的位置,这样才可以构建整个层次结构。



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

  • 问题内容: 我需要一个从任何参数构建JSON有效字符串的函数,但: 通过不两次添加对象来避免递归问题 通过截断给定深度来避免调用堆栈大小问题 通常,它应该能够处理大对象,但要以截断为代价。 作为参考,此代码失败: 避免递归问题很简单: 但是到目前为止,除了复制和更改Douglas Crockford的代码 以跟踪深度之外,我还没有找到任何方法来避免在诸如或any之类的非常深的对象上发生堆栈溢出。有

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

  • 我想将Nightwatch的页面对象系统用于我们应用程序中使用的UI组件。因为nightwatch有自己的读取/初始化它们的方式,所以我看不到正确扩展/重用它们的方法。 例如,我想要一个“日期字段”的DateInputPageObject。它将识别标签、输入、日期选择器等。 我会在任何带有日期输入字段的页面上使用它。 我还想扩展页面对象。例如,。将为所有模态元素定义选择器-覆盖、容器、关闭按钮等。

  • 据我所知,命名空间std包含所有的C++标准库,其中一个标准库是iostream,它有对象cout和cin。 上面的结构正确吗?还是不同?

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