In this post I will demonstrate the use of ‘Program To Interface’ Design Principle and Object Composition, to emulate Multiple Inheritance in Java. For a refresher on these topics, there’s a very informative post on Artima Developer where Erich Gamma, co-author of the landmark book, Design Patterns, talks with Bill Venners about two design principles: program to an interface, not an implementation, and favor object composition over class inheritance.
For our example, consider different type of Employment Roles available in a typical Software Consulting Firm. To simplify things a bit, assume there are 4 roles; Developer, Tester, Architect and Project Manager. All of these are Employee(s) of the Software Consulting Form i.e. the employer.
Thinking in Object Oriented, you can easily depict that Employee is the Base or Parent Class and Developer, Tester, Architect and ProjectManager are Derived or Child Classes.
This is the simple example of (Single) Inheritance in Java i.e. all the five classes are inheriting a single Parent Class. All the five? yes Employee is inheriting from Object class following the rules of Java Language Specification that if a class is not inherited from any other class then by default it will be inherited from the Object class.
Now, in real world, this happens quite often and specially in a Software Consulting Firm that a person can “perform” the roles of more than one types. For example, given the circumstances and the skill sets:
- A senior technical-management resource can perform the roles of Project Manager, Architect and Developer.
- A senior technical resource can perform the roles of Architect and Developer.
- Project Manager, Architect and Developer can wear the cap of Tester anytime during the project lifecycle.
- So on and so forth
To simplify, let us consider one of the above cases, where we wanted to have a new “role”, which we call “ADP” and this role has the responsibilities of Architect, Developer and Project Manager combined. See the picture below:
The Software Design depicted above is what we want to achieve, but because multiple inheritance is not supported in Java, we will try “emulate” Multiple Inheritance to allow “ADP” to inherit from Architect, Developer and ProjectManager classes.
Java allows us to emulate the behavior of Multiple Inheritance through the use of Interfaces. Java Interfaces are a good way to separate the contract from its actual implementation and which ever the class “implements” the interface will enter into a binding contract to provide implementation of all the methods “declared” in that particular interface, otherwise declares itself as an “abstract” class – an incomplete, non instantiable class.
While a Class in Java can not “extends”/inherit from more than one Classes, it can “implements”/inherit more than one Interfaces. If we can split the contract (method declarations) from the actual implementation (method definitions) of all of our classes above, we would be in a good position to at-least inherit/implement contracts from multiple interfaces – this is also referred to as “Multiple Interface Inheritance”.
The Software Design depicted below now shows each of our classes are now split up into a set of Interface and a corresponding Implementation Class.
Note that Interfaces alone, now form the same hierarchy as show in the first picture above. Similarly implementation Classes alone, form the same hierarchy as shown in the first picture above.
Now, let us make changes to our Software Design to accommodate the ADP Class introduced in second picture above.
Notice how ADP (now an Interface) “extends”/inherits from more than one Parent Interfaces (Emlpoyee, Architect, Developer & ProjectManager). This is very nice as far as Multiple Interface Inheritance is concerned. Our target Interface i.e. ADP now have the method declarations of all the four other Interfaces and following is possible as far ADP Interface alone is concern:
ADP refAdp;
...
refAdp.getEmploeeId();
refAdp.setEmployeeId(1);
refAdp.design();
refAdp.develop();
refAdp.manage();
The last unresolved issue now is the Multiple Implementation Inheritance i.e. support for a Class to inherit from more than one Classes. For that we will use Object Composition and Delegation principles of OOP.
Now, our ADPImpl class have to fulfill the contracts of 4 additional Interfaces (besides its very own ADP Interface) – Employee, Architect, Developer and ProjectManager. Note that all of the methods declared in each of the Interfaces have their matching implementation already available in corresponding Implementation classes. And, our intent here is to re-use that implementation rather copy-paste or duplicate the code. Once way to re-use implementation is to inherit the class that contains the required implementation, but java allows us to inherit implementations from only one class.
Question: Which one of these 4 classes (Employee, Architect, Developer, ProjectManager) is the best candidate for Implementation Inheritance for ADP class and why?
Answer: Employee class, because person with ADP role (or any other role) “is an” Employee first. A person who is not an Employee can not work as an Architect, Developer, ADP, etc..
So let us now extend/inherit our ADPImpl class from EmployeeImpl class.
One down! 3 more to go
We have now exhaust the Implementation Inheritance option and can not use it any more for ADPImpl class, so lets move on to Object Composition.
Object composition is a tightly coupled form of association and it requires ownership of the composed object. So much that the Composed Object may not exists without the existence of Container Object, and if a Container object dies than the Composed object should be disposed off as well. This form of relationship is also called “has a” relationship.
{Do note that there’s another loosely coupled form of association available and is called “Aggregation”}
ADP “is an” Employee and ADP “has an” Architect role – make sense?
Look at the picture above, ADPImpl is still complaining us to provide the implementation for design(), develop() and manage() methods which are declared in Architect, Developer and ProjectManager Interfaces. We already have the implementation of these methods in implementation classes ArchitectImpl, DeveloperImpl and ProjectManagerImpl respectively.
We will now use the Object Composition and Method Delegation to try to re-use the implementations rather than copy-pasting or duplicating the logic/code.
DOWNLOAD COMPLETE SOURCE FROM HERE
UPDATE: I’ve published an open source project “Project MI+” which will helps you in (functionally) inherit from multiple classes, saving you from writing a lot of boiler late code. Importantly, it uses all of the above mentioned concepts to achieve that, plus a of couple more to come even closer.
Using Project MI+, you can re-write ADP interface as follows:
package smhumayun.codeoftheday.MultipleInheritanceExample;
@MISupport(parentClasses={EmployeeImpl.class, ArchitectImpl.class, DeveloperImpl.class, ProjectManagerImpl.class})
public interface ADP extends Employee, Architect, Developer, ProjectManager {
}
You won’t need ADPImpl now and can instantiate ADP objects using Project MI+’s factory as follows:
ADP adp = miFactory.newInstance(ADP.class);
adp.getEmployeeId();
adp.design();
adp.develop();
adp.manage();
No comments:
Post a Comment