aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes subclass vs compostion Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "subclass vs compostion" Watch "subclass vs compostion" New topic
Author

subclass vs compostion

william kane
Ranch Hand

Joined: Nov 21, 2000
Posts: 260
Hi,
I have a problem relating the merit of composition over inheritance as advocated by most of the design patterns.
The most common merit by using composition is that you can change the behaviour at runtime and by using inheritance behaviour is associated with a class at compile time itself and therefore cannot be changed at run time.
What does this mean?
For Ex. Lets say there is a Leave application system that is used by both supervisors and subordinates.When the supervisor clicks on Apply leave button the leave is instantly updated in the system.But when a subordinate clicks on the apply leave button the leave is posted for approval from supervisor.

There are two ways to address this requirement
1.Have any employee super class with applyLeave(int no of days) method and have Supervisor and Subordinate subclasses override that method to cater to business rule stated above.
2.Have a Employee class with the Role object composed in it and have Supervisor and Subordinate implement the applyLeave method in the role interface.

I can still change the behaviour of the Employee class at runtime by assinging it the Supervisor or Subordinate instance based on login.
If the system had a swing interface the actionPerformed for the Apply leave button would be...
actionPerformed{
Employee emp=null;
if(login=='Supervisor'){
emp=new Supervisor();
emp.applyLeave();
}else{
if(login=='Subordinate'){
emp=new Subordinate();
emp.applyLeave();
}

I can achive a similar result by interchanging the role objects too.

So why can inhertance be used to change behaviour at run time.

Thanks in advance
William


Help me!Help you!!!
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 1012
    
    3
Originally posted by william kane:
Hi,
I have a problem relating the merit of composition over inheritance as advocated by most of the design patterns.
The most common merit by using composition is that you can change the behaviour at runtime and by using inheritance behaviour is associated with a class at compile time itself and therefore cannot be changed at run time.
What does this mean?
For Ex. Lets say there is a Leave application system that is used by both supervisors and subordinates.When the supervisor clicks on Apply leave button the leave is instantly updated in the system.But when a subordinate clicks on the apply leave button the leave is posted for approval from supervisor.

There are two ways to address this requirement
1.Have any employee super class with applyLeave(int no of days) method and have Supervisor and Subordinate subclasses override that method to cater to business rule stated above.
2.Have a Employee class with the Role object composed in it and have Supervisor and Subordinate implement the applyLeave method in the role interface.

I can still change the behaviour of the Employee class at runtime by assinging it the Supervisor or Subordinate instance based on login.
If the system had a swing interface the actionPerformed for the Apply leave button would be...
actionPerformed{
Employee emp=null;
if(login=='Supervisor'){
emp=new Supervisor();
emp.applyLeave();
}else{
if(login=='Subordinate'){
emp=new Subordinate();
emp.applyLeave();
}

I can achive a similar result by interchanging the role objects too.

So why can inhertance be used to change behaviour at run time.

Thanks in advance
William


Your other topic on when to subclass and Decorators provides a good example of the advantage of composition over subclassing. Rather than having a separate subclass for each possible combination of car options, it's easier to have one class represent the base car, another to represent the additional/modified functionality/values incurred by having a stereo, another for having A/C, etc.

As for compile time vs run time flexibility...
Again, your Car example shows this. Once you have a bundle of (in this case) Decorators, you can put hem together at run time in different combinations rather than precalculating all possible combinations at program/compile time and making a separate subclass for each.

This is especially helpful if you don't want to have to completely implement every combination. For instance, at program/compile time you might not bother implementing a class for HighEndCarWithACNoStereo because you didn't think anyone would buy a "high end" car without a stereo. But then a deaf person walks into your dealership and wants to purchase just such a car. With composition you have the flexibility to construct such an complex object at run time. If you relied on compile time inheritance, you'd be in trouble.

Now that's not to say that composition is always better than subclassing. In fact, the uses of composition illustrated in Design Patterns use inheritance. It's just a question of what you subclass and what other classes have to know about the subclassing. You have to look at each case individually.

It's just like golf: sometimes you use your mashie, sometimes your niblick.

Does this help at all?

Ryan
william kane
Ranch Hand

Joined: Nov 21, 2000
Posts: 260
Thanks Ryan,
That did clear a lot of things for me.
-William
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by william kane:
I can still change the behaviour of the Employee class at runtime by assinging it the Supervisor or Subordinate instance based on login.


True - but once you have instanciated the employee, you can't change its behaviour. With Strategy, you could change the behaviour of an existing Employee instance by just replacing its strategy.

Robert C. Martin has written a very nice article on this topic: http://today.java.net/pub/a/today/2004/10/29/patterns.html


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 1012
    
    3
Originally posted by Ilja Preuss:

True - but once you have instanciated the employee, you can't change its behaviour. With Strategy, you could change the behaviour of an existing Employee instance by just replacing its strategy.


Or another way to look at the original example is to say that you're changing the run time behavior of the class containing actionPerformed() via composition with either a Supervisor or Subordinate object. i.e. The Supervisor and Subordinate objects are acting as Strategy objects in that you pick one at run time to perform the correct action.

Ryan
Balachandran Paranjothimani
Ranch Hand

Joined: Jun 18, 2005
Posts: 43
Originally posted by Ilja Preuss:


Robert C. Martin has written a very nice article on this topic: http://today.java.net/pub/a/today/2004/10/29/patterns.html


I just read the article. The second design that shows the Logger with abstract format method and its relationship with the Recorder interface is actually a Bridge Pattern. We are able to decouple the interface and implementation by separating them out into separate hierarchy. Wonder why it was not even mentioned in the article!


Moderator : <a href="http://groups.yahoo.com/group/OOAD_UML/" target="_blank" rel="nofollow">http://groups.yahoo.com/group/OOAD_UML/</a><br />Home : <a href="http://www.zepho.com" target="_blank" rel="nofollow">http://www.zepho.com</a>
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Balachandran Paranjothimani:


I just read the article. The second design that shows the Logger with abstract format method and its relationship with the Recorder interface is actually a Bridge Pattern. We are able to decouple the interface and implementation by separating them out into separate hierarchy. Wonder why it was not even mentioned in the article!


You mean, like in the very last sentence: "This problem is common enough that the combined use of Strategy and Template Method to solve it (as we did in the previous example) is a pattern in and of itself, called Bridge."?
Balachandran Paranjothimani
Ranch Hand

Joined: Jun 18, 2005
Posts: 43
You are right. I just skimmed through the article. Uncle Bob rocks!
 
Consider Paul's rocket mass heater.
 
subject: subclass vs compostion