Composition vs. Delegation
Is there any difference in terms of implementation as how a composition design can be different from delegation. For example the code below seems to be doing delegation since the user cann开发者_如何学运维ot access the composed object (i.e "a") without using b. Hence, the user would need to invoke interfaces of class b and then "class b" invoke appropriate interfaces of "class a" making it delegation. Does this make sense ?
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
};
The term "composition" is usually used in terms of object modelling as an expression of a "has-a" relationship and is a form of association (another being aggregation). This is usually contrasted with "inheritance" ("is-a" relationship). So:
What's the difference between composition and aggregation? Composition implies that the child cannot exist without the context of the parent.
For example, a House has one or more Rooms. That's a composition relationship. Delete the house and the rooms also cease to exist. A House also has a number of occupants, being instances of Person. That's an aggregation relationship because those people exist outside of the context of that house.
Delegation is nothing more than an implementation detail. A class has a public interface that describes its state and behaviour. How that is implemented is irrelevant. It could delegate to other objects or not.
You'll note that both A and B from your example have the same external interface. It's more common to do something like this:
// this represents an interface
class A {
public:
virtual void printStructure() = 0;
}
with concrete classes:
class ConcreteA : A {
public:
virtual void printStructure() { ... }
}
and
class DelegateA : A {
public:
DelegateA(A& a) { this.a = a; }
virtual void printStructure() { a.printStructure(); }
private:
A a;
}
Excuse my probably C++ syntax errors. I'm a little rusty.
There are a couple of differences I see:
- Delegation involves re-exporting methods; in a composition relationship, the inner objects methods may be used only privately and not re-exposed.
- Composition usually implies some kind of ownership semantics with implications for object lifecycle; the parent object "owns" the child and the child doesn't have much reason to exist on its own. Delegation does not have this implication.
The code you show uses delegation and association; the association may be composition, but it's difficult to tell without broader context or more information about the objects (it can be quite subtle and subjective when an association becomes a composition).
Composition is about the relationships between objects.
Delegation is about passing work from one object to another.
These are actually different (but sometimes related) concerns.
What you've got is B composed of A (B refers to A). B also delegates its one method to A.
But since B's use of A is private (fully encapsulated within B's black box), I wouldn't call B's use of A "composition". I would use "composition" only if class A could be accessed from B. What's important here is if B's logical model "has-a" A.
In your case, B is implemented in terms of A. Since this is an implementation concern it can be considered as not part of B's logical model. That is, you can talk intelligently about B without talking or caring about A.
That all said, this stuff is really only important to PHB's and UML modeling tools. Or perhaps if you are studying Design Patterns. I wouldn't get too hung up on it.
[PHB => Pointy Haired Boss]
精彩评论