Wednesday, September 11, 2013

Composition with Interfaces - The best of the two worlds.


It is essential in Java to understand the sense of interfaces. It is straightforward that Java API is designed not give the access to specific capabilities but to define abstract interface through which your programs talks to the underlying source. For example this is how SWING works giving you the interface GUI same on any machine running JVM.
Java encourage separation of interface from implementation with use of java interface construct.
Dividing code to functional parts and defining communication using interfaces is the most general rule of software design. In Java interface is a 100% abstract interface for interaction with the code implementing it. Other words there is common interface for communication of different implementations.

We have already talked about the other aspect - composition in articles [see1][see2]. We have talked about some advantages of flexibility concerning composition.
We need to elaborate more on one “disadvantage” of composition regarding inheritance. That is that it is easier to add new subclass in inheritance (because of polymorphism) that to add new front-end class in composition unless composition comes with interfaces.

Let us present example to express the polymorphism of composition with interfaces.

interface CanTurn {
    void turn();
}

class Vehicle {
    public void turn() {
        System.out.println("Turnning Car.");
    }
}

class Car implements CanTurn {

     private Vehicle vehicle = new Vehicle();
     public void turn() {
         return vehicle.turn();
     }
}


class Driver{
     static void turnMachine(CanTurn item) {
         item.turn();
     }
}

class MainClass{

       public static void main(String[] args) {
              Car car = new Car();
               Driver.turnMachine(car);
        }
}


But now we have an interface that lets us create a new class:

class Bike implements CanTurn {

       private Vehicle vehicle = new Vehicle();

       public void turn() {
                return vehicle.turn();
        }
}

Car and Bike both has a composition relationship with Vehicle. We reuse a Vehicle’s implementation of turn() method using explicit delegation i.e. invoking turn() on it own Vehicle object. On the other hand Bike can also be passed to turnMachine() method from Driver class because Bike also implements interface CanTurn.
As we have mentioned composition is more flexible but inheritance is easier to understand.


The considerations about composition and inheritance are in the other article but the general rule that holds is that:
if  (relationship is a permanent IS-A relationship along the application){
     use inheritance
}else{
      use composition
}

Summary


Interface is a tool for achieving flexibility in Java. Any class can provide  an implementation of an interface. Not changing the interface is crucial. Apart from changing interface all changes to implementation classes or adding new classes does not impact the code that is based only on the interface.
In any subsystem that may have many implementations with a common abstraction interface there needs to be a Java interface on top of it. By dint of this approach any client wanting to use this subsystem can easily utilize any of the implementations without need to take care of their mechanisms. Just as it is in case of JVM and operating systems. This assures low or none coupling between parts of your system. What is more the code is more easily changed, extended and customized. The flexibility of code is something that comes with interfaces and brings all of the goodies of composition to the land of polymorphism. The best of the two worlds.

No comments :

Post a Comment

Social Buttons End POst