views:

4704

answers:

3

Hello,

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

I have consulted an 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)??

Many thanks in advance.

+6  A: 

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 likley 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

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

the realtionship between the objectes lasts only as long as the intern is fetching the coffee, then it returns to the resource pool.

ChssPly76
Thanks for pointing out the previous discussions. So, in terms of how the code looks like, all 3 cases should looks pretty much the same? referencing other object(s)?
denchr
More or less. In case of delegation the reference may be obtained from elsewhere (you may even be delegating to static methods); in case of composition nested objects are created by or with help of parent object (since it controls their lifetimes); and in case of aggregation nested object instances are injected (usually during construction / initialization).
ChssPly76
@ChssPly76: hope you don't mind, I've tried to answer the supplementary.
djna
@djna - sure thing, thank you for providing detailed code examples
ChssPly76
+3  A: 

Your book explains quite good so let me elaborate and provide you some examples.

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

Sometime a class may logically need to be big. But big class is not a good coding pratice. Also sometime, some functionalities of a class may be implementable in more than one way and you may want to change that some time.


class FeatureHolder {
 void feature() {
  // Big implementation of the feature that you dont want to put in the class Big
 }
}

class Big {
 private FeatureHolder FH = new FeatureHolder();

 void feature() {
  // Delegate to FeatureHolder.
  FH.feature();
 }

 //.. Other features
}

From the above example, Big.feature() call feature of FH as is without changing it. This way, the class Big does not need to contain the implementation of the feature (separation of labour). Also, feature() can implement differently by other class like "NewFeatureHolder" and Big may choose to use the new feature holder instead.

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

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

Technially, Composition is "part of" and Aggregation is "refer to" relationship. Your arms are part of you. If you no longer live, your arm will die too. Your cloth is not part of you but you have them; as you can guest, your cloth does not go with you.

In programming, some objects are part of another object and they have no logical meaning without it. For example, a button is composed into a window frame. If a frame is closed, the button has no reason to be around anymore (Composition). A button may have reference to a database (like to refreash data); when the button is eliminated, the database may still be around (Aggregation).

Sorry for my English, Hope this helps

NawaMan
A: 

Delegation

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

  public void method() {
    b.method();
  }
}

When clients of A call method, class A delegates the method call to B.

Rationale. Class A can inherit from one class, but expose behaviours that belong elsewhere.

Further Study. http://beust.com/java-delegation.html

Composition

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

  public A() {
  }
}

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

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

Further Study. http://www.artima.com/designtechniques/compoinh.html

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. http://faq.javaranch.com/java/AssociationVsAggregationVsComposition

Demonstration Without References

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

Dave Jarvis