In Depth Interface Driven Programming in Java

3 min read

In Depth Interface Driven Programming in Java

Interface driven programming is a very common term for Java (and also for many other languages) developers. Many junior developers might have got review comments to follow this programming practice. As a result, we define an interface, implement it, and declare that we are following this practice. But is this practice as simple as defining interface, implementing it and using it to declare variables? Why is it so important? How can it prove beneficial to entire application? These and many more questions are discussed below in depth.

What is Interface Driven Programming?

All of us know what an interface is. In simple terms it is a set of method declarations and optionally constant attributes. For interface driven programming, let us leave the constant variables aside, because this programming practice uses only method declaration feature of interface. Variables do not play any role. Interface is highest level of abstraction, a contract defining what definitions of different methods are. Each method, in an interface represents certain behavior.

Let us take popular example, used to explain OOPs concepts, of classes implementing and interface and further using these classes.

Class Diagram

Below is Java implementation of above classes.

Vehicle.java

package net.deepakgaikwad.idp;

public interface Vehicle {
	public void drive();
}

In vehicle interface, we have drive() method, which defines driving behavior of classes implementing this interface. Below are two implementation variances of our Vehicle interface – Car and Truck.

Car.java

package net.deepakgaikwad.idp;

public class Car implements Vehicle {

	@Override
	public void drive() {
		System.out.println("Driving a Car");

	}

}

Truck.java

package net.deepakgaikwad.idp;

public class Truck implements Vehicle {

	@Override
	public void drive() {
		System.out.println("Driving a Truck");

	}

}

Now, we use these classes to drive() car and truck using Driver class below.

Driver.java

package net.deepakgaikwad.idp;

public class Driver {

	public void driveCar(Car car){
		car.drive();
	}

	public void driveVehicle(Vehicle vehicle){
		vehicle.drive();
	}

	public static void main(String[] args){
		Driver driver = new Driver();

		driver.driveCar(new Car());

		driver.driveVehicle(new Car());

		driver.driveVehicle(new Truck());

	}
}

We can clearly see ability of driveVehicle() method to drive Car as well As Truck while driveCar() method can only drive car. Reason is the input variable type. We have used interface Vehicle to declare driveVehicle() method input. It allows us to pass instance of any class that implements this Interface to this method.

In short, declaring variables of interface type instead of concrete class type is Interface Driven Programming.

Implementing Polymorphism through Interface Driven Programming

First question is what is polymorphism? Instead of getting into details of polymorphism, we refer simple meaning of it – multiple forms. Input of driveVehicle() method is declared using Interface hence any class that implements this interface can be an input. This input can take change its form to as many types as the number of implementation of Vehicle interface.

Open Close Principle and Interface Driven Programming

Open close principle keeps a class (design/code) open for extension but closed for modification. The core is – it should be possible to add new functionality with minimum change, and without impacting existing stable code. If we use interface driven programming and in above example we want to add functionality for Bus, it is just adding a Bus class which implements same Vehicle interface, and that’s it. We don’t need to do anything more, no need to change Driver class driveVehicle() method as it is alrady enabled to drive anything of Vehicle type. But if it is coded the way driveCar() method input is, then it will require lot more code change and testing of existing code as well.

Where to Use Interface Driven Programming

The answer is not everywhere. While designing an application, if you can visualize possibility of polymorphic behavior, then go for interface driven programming.

Implementing Interface Driven Programming in Spring

When we are using dependency injection of Spring, we can declare variable of Vehicle type in Driver (SpringDriver) class above.

SpringDriver.java

package net.deepakgaikwad.idp;

public class SpringDriver {

	private Vehicle vehicle;

	public Vehicle getVehicle() {
		return vehicle;
	}

	public void setVehicle(Vehicle vehicle) {
		this.vehicle = vehicle;
	}

	public void driveCar(Car car){
		car.drive();
	}

	public void driveVehicle() {
		vehicle.drive();
	}

	public static void main(String[] args){
		SpringDriver driver = new SpringDriver();

		driver.driveCar(new Car());
		driver.driveVehicle();

	}
}

Spring Configuration that will be required to inject Car and Truck class instances into SpringDriver is as shown below. In this configuration we are injecting Car object. If we want to change it to Truck just change the “vehicle” property value to reference “truck” bean.

<bean id=“springDriver">
                <property name=“vehicle">
                                <ref bean=" car" />
                </property>
</bean>
<bean id=“car" />
<bean id=“truck" />

Benefits of Interface Driven Programming

  • Ability to implement polymorphism
  • Better reuse
  • Reduction in maintenance cost
  • Reduced coupling between classes
  • Reduction in testing cost as the amount of code requiring testing is reduced.

Disadvantages of Interface Driven Programming

  • Runtime change in behavior makes it difficult to visualize all problems during coding and review. One has to wait till testing phase to reveal some of the defects. This is challenge with polymorphism than Interface Driven Programming
  • Cannot autowire classes with Spring
  • Extensive use of interfaces can reduce readability of code

Leave a Reply

Your email address will not be published. Required fields are marked *