20 votes

Composition ou délégation

Existe-t-il une différence en termes de mise en œuvre ? En effet, la conception de la composition peut être différente de la délégation. Par exemple, le code ci-dessous semble faire de la délégation puisque l'utilisateur ne peut pas accéder à l'objet composé (c'est-à-dire "a") sans utiliser b. Par conséquent, l'utilisateur devrait invoquer les interfaces de la classe b et ensuite la "classe b" invoque les interfaces appropriées de la "classe a", ce qui fait de la délégation. Cela a-t-il un sens ?

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
};

40voto

cletus Points 276888

Le terme "composition" est généralement utilisé en termes de modélisation d'objets comme l'expression d'une relation "has-a" et est une forme d'association (une autre étant l'agrégation). On l'oppose généralement à l'"héritage" (relation "est"). Ainsi :

Quelle est la différence entre la composition et l'agrégation ? La composition implique que l'enfant ne peut exister sans le contexte du parent.

Par exemple, une maison comporte une ou plusieurs chambres. Il s'agit d'une relation de composition. Supprimez la maison et les chambres cessent également d'exister. Une maison a également un certain nombre d'occupants, qui sont des instances de Personne. Il s'agit d'une relation d'agrégation, car ces personnes existent en dehors du contexte de la maison.

La délégation n'est rien d'autre qu'un détail de mise en œuvre. Une classe possède une interface publique qui décrit son état et son comportement. La façon dont elle est implémentée n'est pas pertinente. Elle peut déléguer à d'autres objets ou non.

Vous noterez que A et B de votre exemple ont tous deux la même interface externe. Il est plus courant de faire quelque chose comme ceci :

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

avec des classes concrètes :

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

y

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

Excusez mes erreurs de syntaxe probablement C++. Je suis un peu rouillé.

11voto

Michael Ekstrand Points 12849

Il y a quelques différences que je vois :

  • La délégation implique la réexportation des méthodes ; dans une relation de composition, les méthodes des objets internes ne peuvent être utilisées que de manière privée et ne sont pas réexposées.
  • La composition implique généralement une sorte de sémantique de propriété avec des implications pour le cycle de vie des objets ; l'objet parent "possède" l'enfant et l'enfant n'a pas beaucoup de raison d'exister par lui-même. La délégation n'a pas cette implication.

Le code que vous montrez utilise la délégation et l'association ; l'association peut être une composition, mais il est difficile de le dire sans un contexte plus large ou plus d'informations sur les objets (cela peut être assez subtil et subjectif quand une association devient une composition).

5voto

rickmode Points 79

La composition concerne les relations entre les objets.

La délégation consiste à transmettre le travail d'un objet à un autre.

Il s'agit en fait de préoccupations différentes (mais parfois liées).

Ce que vous avez, c'est B composé de A (B se réfère à A). B délègue également sa méthode unique à A.

Mais puisque l'utilisation de A par B est privée (entièrement encapsulée dans la boîte noire de B), je n'appellerais pas l'utilisation de A par B une "composition". Je n'utiliserais le terme "composition" que si la classe A était accessible depuis B. Ce qui est important ici, c'est de savoir si le modèle logique de B "a-a" A.

Dans votre cas, B est implémenté en termes de A. Puisqu'il s'agit d'une préoccupation d'implémentation, on peut considérer qu'elle ne fait pas partie du modèle logique de B. En d'autres termes, vous pouvez parler intelligemment de B sans parler ou vous soucier de A.

Cela dit, ces éléments ne sont vraiment importants que pour les PHB et les outils de modélisation UML. Ou peut-être si vous étudiez les Design Patterns. Je ne m'y attacherais pas trop.

[PHB => Boss aux cheveux pointus]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X