组合与代表团

时间:2010-01-26 02:37:00

标签: composition delegation

在实施方面,组合设计与授权的区别是否有所不同。例如,下面的代码似乎正在进行委托,因为用户不能在不使用b的情况下访问组合对象(即“a”)。因此,用户需要调用类b的接口,然后“class b”调用“class a”的适当接口,使其成为委托。这有意义吗?

Class A {
friend class B;
private: 
A(){}; //dont want user to instantiate this class object since it wont sense without any context. Just like a room with no house.
void PrintStructure(){};
};

Class B{
public:
void PrintStructure(){a.PrintStructure();} //delegate

private:
A a; //composition
};

3 个答案:

答案 0 :(得分:35)

术语“组合”通常用于对象建模,作为“has-a”关系的表达,并且是一种关联形式(另一种是聚合)。这通常与“继承”(“is-a”关系)形成对比。所以:

构图和聚合之间有什么区别?组合意味着没有父母的背景,孩子就不能存在。

例如,House有一个或多个房间。这是一种构图关系。删除房子,房间也不复存在。众议院也有许多人,是人的实例。这是一种聚合关系,因为那些人​​存在于那个房子的背景之外。

委托只不过是一个实施细节。类具有描述其状态和行为的公共接口。如何实施是无关紧要的。它可以委托给其他对象。

您会注意到示例中的A和B都具有相同的外部接口。做这样的事情更常见:

// this represents an interface
class A {
public:
  virtual void printStructure() = 0;
}

具体课程:

class ConcreteA : A {
public:
  virtual void printStructure() { ... }
}

class DelegateA : A {
public:
  DelegateA(A& a) { this.a = a; }
  virtual void printStructure() { a.printStructure(); }
private:
  A a;
}

请原谅我可能的C ++语法错误。我有点生气。

答案 1 :(得分:8)

我看到了一些不同之处:

  • 授权涉及重新导出方法;在组合关系中,内部对象方法只能私下使用而不能重新暴露。
  • 组合通常意味着某种所有权语义,对对象生命周期有影响;父对象“拥有”孩子,孩子没有太多理由独自存在。代表团没有这个含义。

您展示的代码使用委托和关联;关联可能是组合,但如果没有更广泛的背景或关于对象的更多信息很难说(当关联成为一个组合时,它可能是非常微妙和主观的。)

答案 2 :(得分:4)

构图是关于对象之间的关系。

委托是指将工作从一个对象传递到另一个对象。

这些实际上是不同的(但有时是相关的)问题。

你得到的是由A组成的B(B指的是A)。 B还将其一种方法委托给A。

但由于B使用A是私有的(完全封装在B的黑盒子里),我不会称B使用A“组合”。只有当A类可以从B访问时,我才会使用“组合”。这里重要的是B的逻辑模型是否具有“a”A。

在你的情况下,B是用A来实现的。由于这是一个实现问题,它可以被认为不是B的逻辑模型的一部分。也就是说,你可以在不谈论或关心A的情况下聪明地谈论B。

大家都这么说,这些东西对PHB和UML建模工具来说真的很重要。或者,如果你正在研究设计模式。我不会太挂在它上面。

[PHB => Pointy Haired Boss]