Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distinguishing between delegation, composition and aggregation (Java OO Design)

I am facing a continuing problem distinguishing delegation, composition and aggregation from each other, and identifying the cases where it's the best to use one over the other.

I have consulted a Java OO Analysis and Design book, but my confusion still remains. The main explanation is this:

Delegation: When my object uses another object's functionality as is without changing it.

Composition: My object consists of other objects which in turn cannot exist after my object is destroyed-garbage collected.

Aggregation: My object consists of other objects which can live even after my object is destroyed.

Is it possible to have a few simple examples demonstrating each case, and the reasoning behind them? How else can these examples be demonstrated other than my object simply having a reference to another object(s)?

like image 549
denchr Avatar asked Sep 05 '09 22:09

denchr


2 Answers

Delegation

public class A {   private B b = new B();    public void methodA() {     b.methodB();   } } 

When clients of A call methodA, class A delegates the call to B's methodB.

Rationale. Class A exposes behaviours that belong elsewhere. This can happen in single-inheritance languages where class A inherits from one class, but its clients need behaviours that are implemented in a different class. Further study.

Hybrid Delegation

public class A {   private B b = new B();    public void methodA() {     b.methodB( this );   } } 

The difference between delegation that involves simple forwarding and delegation that acts as a substitute for inheritance is that the callee must accept a parameter of the caller, exemplified as:

    b.methodB( this ); 

Rationale. Allows class B instances to use functionality available from class A, just as class B would if it inherited from class A--but without inheritance. Further study.

Composition

public class A {   private B b = new B();    public A() {   } } 

Once no more references to a particular instance of class A exist, its instance of class B is destroyed.

Rationale. Allows classes to define behaviours and attributes in a modular fashion. Further study.

Aggregation

public class A {   private B b;    public A( B b ) {     this.b = b;   } }  public class C {   private B b = new B();    public C() {     A a = new A( this.b );   } } 

Once there are no more references to a particular instance of class A, its instance of class B will not be destroyed. In this example, both A and C must be garbage collected before B will be destroyed.

Rationale. Allows instances to reuse objects. Further study.

Demonstration Without References

The names given to these simple patterns are defined by their referential relationships.

like image 160
Dave Jarvis Avatar answered Sep 22 '22 17:09

Dave Jarvis


Your object would reference another object(s) in all three cases. The difference lies in behavior and / or lifecycle of referenced objects. Some examples:

  1. Composition: House contains one or more rooms. Room's lifetime is controlled by House as Room will not exist without House.

  2. Aggregation: Toy house built from blocks. You can disassemble it but blocks will remain.

  3. Delegation: Your boss asked you to get him a coffee, you've had an intern do it for you instead. Delegation is not a type of association (like composition / aggregation are). The latter two have been discussed on Stack Overflow many times

In the comment you ask how the implementation would differ in each case, observing that in all cases we invoke methods on the releated objects. It's true that in each case we would have code such as

myRoom.doWork();  myBlock.doWork();  myMinion.doWork(); 

but the differences lie in the life-cycle and cardinality of the related objects.

For the Component, the Rooms come into existence when the House is created. So we might create them in the constructor of the House.

In the case of Association (I'll use Tyre and Car) Cars might add Tyres in their constructor, but later you may want to remove and change tyres. So you also have methods such as

 removeTyre(FrontLeft)  addNewTyre(aTyre, BackRight) 

And it's quite likely that the aTyre object came from a Factory - we didn't new it in any of the Car's methods.

In the case of Delegation, you might not even have a member variable to hold the delegate

 resourcingPool().getIntern().getCoffee(SkinnyLatte, workstation 7); 

the relationship between the objects lasts only as long as the intern is fetching the coffee. Then it returns to the resource pool.

like image 22
ChssPly76 Avatar answered Sep 24 '22 17:09

ChssPly76