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

denchr picture denchr · Sep 6, 2009 · Viewed 40.5k times · Source

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)?

Answer

Dave Jarvis picture Dave Jarvis · Sep 6, 2009

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.