20

在实现方面是否有任何区别,因为组合设计与委托不同。例如,下面的代码似乎在进行委托,因为用户不使用 b 就无法访问组合对象(即“a”)。因此,用户需要调用 b 类的接口,然后“b 类”调用“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
};
4

3 回答 3

40

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

组合和聚合有什么区别?组合意味着孩子不能没有父母的上下文而存在。

例如,一所房子有一个或多个房间。那是一种组合关系。删除房子,房间也不再存在。House 也有许多居住者,它们是 Person 的实例。这是一种聚合关系,因为这些人存在于那所房子的环境之外。

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

您会注意到示例中的 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++ 语法错误。我有点生疏了。

于 2010-01-26T02:46:42.397 回答
11

我看到有几个不同之处:

  • 授权涉及再出口方法;在组合关系中,内部对象方法只能私下使用,不能重新公开。
  • 组合通常意味着某种对对象生命周期有影响的所有权语义;父对象“拥有”子对象,而子对象没有太多理由单独存在。委托没有这个含义。

您显示的代码使用委托和关联;关联可能是组合,但如果没有更广泛的上下文或有关对象的更多信息,则很难分辨(当关联成为组合时,它可能非常微妙和主观)。

于 2010-01-26T02:39:44.777 回答
5

组合是关于对象之间的关系。

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

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

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

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

在您的情况下,B 是根据 A 实现的。由于这是一个实现问题,因此可以将其视为 B 逻辑模型的一部分。也就是说,你可以聪明地谈论 B,而不用谈论或关心 A。

话虽如此,这些东西实际上只对 PHB 和 UML 建模工具很重要。或者,如果您正在学习设计模式。我不会太挂断它。

[PHB => 尖头发的老板]

于 2010-01-26T03:45:45.647 回答