Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 复合设计模式子组件_Design Patterns_Composite - Fatal编程技术网

Design patterns 复合设计模式子组件

Design patterns 复合设计模式子组件,design-patterns,composite,Design Patterns,Composite,我发现,有了复合模式,有一件事可以用不同的方法来解决:对另一种复合模式的养育 我的意思是,如果“child”元素应该知道“parent”元素,那么可以通过两种方式实现: 通过将父元素放入构造函数: Composite (Composite parent) { parent.addChild(this); this.parent = parent; } public void addChild(Composite child) { children.add(child);

我发现,有了复合模式,有一件事可以用不同的方法来解决:对另一种复合模式的养育

我的意思是,如果“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);
    }
    
现在,我的问题是使用哪种方法?哪一个更可靠、更灵活、更不容易出错?有谁同时经历过这两种方法并决定选择其中一种方法吗?

引用

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

由于其思想是将一组对象视为单个对象(相同类型),因此复合对象通常会迭代其组(子对象),以传播相同的行为。从这个角度来看,在父对象中保留子对象列表更有意义

更新:我误解了你的问题。让我再试一次:出于上述原因,复合对象通常会保留对其子对象的引用。父链接可能(或不)过多。为什么要保留对父对象的引用?孩子们之间有共同的状态吗

更新2:好的,父链接应该在那里。在本例中,您提到的两种方法在功能上是等效的,这本质上是一个API设计问题。一种TDD式的思维方式可以在这里帮助你。例如,由于场景图本质上是一棵树,因此创建第一个节点是一个简单的场景。在两个版本中,您都会这样做(据我所知):


如果您有这样的需求,重新建立节点的父级可能是另一个有趣的测试。确定最重要的操作并进行设计将以最合适的方式塑造API。

是的,我知道。。。但我忘了将子项添加到构造函数中的子项列表中。。。我会马上修好的事实上我不是那个意思。但是现在我发现我误解了你的问题。可能有很多原因需要保留到父元素的链接。在我的例子中,我正在开发GUI库和3D场景图。GUI的子元素必须知道什么是父剪辑区域,这样它们就不会超出父边界。对于scenegraph,它用于创建嵌套变换-当父对象旋转时,子对象与父对象一起旋转,因此必须知道父对象当前的变换。我理解复合设计模式,您实际上复制了问题中的代码。实际上你让我想了想。我不知道TDD代表什么,但是如果你谈论测试驱动设计,我们在讨论中没有什么意义,因为TTD的核心不是语义。我想要的是一个场景的例子,在这些场景中,事情可能会成为问题,或者,以另一种方式,它们可以减轻所有的痛苦,让代码变得真正好。以Swing为例,SWT-SWT在构造函数中接受父类,而Swing使用“addChild”方法。我的问题是“为什么”?我想你没抓住重点。你会问:“哪一个更可靠、更灵活、更不容易出错?”我的答案是,这取决于你。我在代码中添加了我的比较作为注释,但我们不知道您的确切需求,因此我的建议是使用您自己的场景进行测试,然后这些场景将塑造您的设计。这里的TDD代表测试驱动的开发。它有助于以足够小的方式设计API,这与语义IMO非常相关。上面的代码是您在这个意义上提到的API的使用示例,而不是重复的。
// 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);