我发现复合模式有一个可以通过不同方式解决的问题:对其他复合材料的养育。
我的意思是,如果“child”元素应该知道“parent”元素,这可以通过两种方式完成:
将父元素放入构造函数:
Composite (Composite parent) {
parent.addChild(this);
this.parent = parent;
}
public void addChild(Composite child) {
children.add(child);
}
使用addChild方法在内部为添加的子项分配自己的引用:
public void addChild(Composite child) {
children.add(child);
child.setParent(this);
}
现在,我的问题是使用哪种方法?哪一个更可靠,更灵活,更不容易出错?是否有人经历过这两种方法并决定选择其中一种方法?
答案 0 :(得分:1)
当客户端忽略差异时,可以使用复合模式 在对象和单个对象的组合之间。
由于这个想法是将一组对象视为一个对象(具有相同类型),因此通常复合对象会遍历其子组(子组件)以传播相同的行为。从这方面来看,保留父母的孩子名单更有意义。
更新:我误解了你的问题。让我再试一次:由于上面的原因,通常复合对象保持对其子节点的引用。父链接可能(或不)超出。为什么要保留对父母的引用?孩子们之间是否有共享状态?
更新2 :好的,父链接应该在那里。在这种情况下,您提到的两种方式在功能上都是等效的,这实际上是一个API设计问题。 TDD-ish思维方式可以帮到你。例如,由于场景图本质上是一棵树,因此一个简单的场景可以创建第一个节点。这就是你在两个版本中的表现(据我所知):
// First way:
// Shorter but still readable. Parent relationship established at construction, so you can count on that the parent property is always at its final state.
Composite root = new Composite(null);
Composite child = new Composite(root);
// Second way:
// Has an extra statement but more explicit. Also slightly more flexible since the parent relationship can be established _after_ construction.
Composite root = new Composite();
Composite child = new Composite();
root.addChild(child);
如果您有这样的要求,也许重新育儿节点可能是另一个有趣的测试。确定最重要的操作并为它们进行设计将以最合适的方式确定API。