在“深度”对象层次结构中使用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上述每个类提供一个类。
Outermost
inner static Builder
但是,这会不会像Builder模式试图解决的那样使事情变得笨拙?我正在考虑类似的东西-这将强制实施“由内而外”的方法- 意味着在将Innermost对象添加到Middle对象之前,必须对其进行完全构造和实例化。但是我们都知道在实践中(尤其是在构建XML或JSON时),我们很少有“及时”的信息来完成此任务。
Innermost
Middle
最终,每个级别的每个属性都将具有变量的机会;并在最后创建对象。否则,最终将使代码的多个级别的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”方法,但是到那时我们应该将所有数据都放在适当的位置,这样才可以构建整个层次结构。