复合设计模式育儿组件

时间:2013-11-27 20:24:02

标签: design-patterns composite

我发现复合模式有一个可以通过不同方式解决的问题:对其他复合材料的养育。

我的意思是,如果“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);
    }
    

现在,我的问题是使用哪种方法?哪一个更可靠,更灵活,更不容易出错?是否有人经历过这两种方法并决定选择其中一种方法?

1 个答案:

答案 0 :(得分:1)

引用wikipedia:

  

当客户端忽略差异时,可以使用复合模式   在对象和单个对象的组合之间。

由于这个想法是将一组对象视为一个对象(具有相同类型),因此通常复合对象会遍历其子组(子组件)以传播相同的行为。从这方面来看,保留父母的孩子名单更有意义。

更新:我误解了你的问题。让我再试一次:由于上面的原因,通常复合对象保持对其子节点的引用。父链接可能(或不)超出。为什么要保留对父母的引用?孩子们之间是否有共享状态?

更新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。