Interface segregation principle in Java

| Reading Time : 4 minutes | #backenddevelopment #Java


Interface Segregation Principle

Interfaces play an important role in Java programming language and they are widely used for abstraction and to support multiple inheritances.

Interface is achieved by using a keyword interface and declare methods in it. Classes can implement interfaces with the implements keyword, and then provide implementations for the declared methods. One of the design principles to keep in mind while writing interfaces is the Interface Segregation Principle.

In Interface Segregation Principle interface should not have methods that implementing classes don’t require. Implementing classes are for no reason forced to provide implementations for those methods it does not require to. An addition of a method or change to a method signature to interface requires changing all classes implemented in this interface.

The Interface Segregation Principle suggests segregating an interface into smaller and highly cohesive interfaces, known as “role interfaces” and each “role interface” declares one or more methods for specific behavior. Thus clients, instead of implementing an interface implements only those “role interfaces” whose methods are relevant.

Bad Example

Consider the requirements of an application that builds different types of transportation vehicles. Each vehicle will have a price and color. Vehicles such as car can start and stop moving while some vehicles such as airplanes can both move and fly. Example interface

Vehicle.java

public interface Vehicle {
    void setPrice(double price);
    void setColor(String color);
    void start();
    void stop();
    void fly();
}

A class that represents an aeroplane can implement the Vehicle interface and provide implementations of all the interface methods. But, imagine a class that represents a car. This is how the Car class will look.

Car.java

public class Car implements Vehicle {
    double price;
    String color;
    @Override
    public void setPrice(double price) {
        this.price = price;
    }
    @Override
    public void setColor(String color) {
        this.color=color;
    }
    @Override
    public void start(){}
    @Override
    public void stop(){}
    @Override
    public void fly(){}    
}

As you can see in the code, Car needs to provide an implementation fly() method, even though it does not require them. This is a violation of the Interface Segregation Principle. These might affect code readability

Good Example

Following the Interface Segregation Principle, we can address the problem of the vehicle interface, solution is- Segregate the Vehicle interface into multiple role interfaces each for specific behavior. In this case, Vehicle interface can be broken down into three interfaces: Toy, Movable, and Flyable.

Vehicle.java

public interface Vehicle {
     void setPrice(double price);
     void setColor(String color);
}

Movable.java

public interface Movable {
    void start();
    void stop();
}

Flyable.java

public interface Flyable {
    void fly();
}

Now Vehicle interface with the setPrice() and setColor() methods as all vehicles will have a price and color, all Vehicle implementation classes can implement this interface. Then, Movable and Flyable interfaces to represent moving and flying behaviors in vehicles.

Implementation

Car.java

public class Car implements Vehicle, Movable {
    double price;
    String color;

    @Override
    public void setPrice(double price) {

        this.price = price;
    }
    @Override
    public void setColor(String color) {

        this.color=color;
    }
    @Override
    public void start(){
        // Implementation
    }
    @Override
    public void stop(){
        // Implementation
    }
}

Aeroplane.java

public class Aeroplane implements Vehicle, Movable, Flyable {
    double price;
    String color;

    @Override
    public void setPrice(double price) {

        this.price = price;
    }

    @Override
    public void setColor(String color) {
     this.color=color;
    }
    @Override
    public void start(){
        // Implementation
    }
    @Override
    public void stop(){
        // Implementation
    }
    @Override
    public void fly(){
        // Implementation
    }
}

Now implementation classes implement those interfaces they are interested in and this helps to remove unnecessary code and is more readable

Next, let’s write a class to create objects of the implementation classes.

VehicleBuilder.java

public class VehicleBuilder {
    public static Car buildCar(){
        ToyHouse toyHouse=new ToyHouse();
        Car car = new Car();
        car.setPrice(15.00);
        car.setColor("green");
        car.start();
        return car;
        }
    public static Aeroplane buildAeroPlane(){
        Aeroplane aeroplane = new Aeroplane();
        aeroplane.setPrice(25.00);
        aeroplane.setColor("red");
        aeroplane.start();
        aeroplane.fly();
        return aeroplane;
    }
}

Summary (Interface Segregation Principle)

Interface Segregation Principle ensures small, focused, and highly cohesive software components. Interface Segregation Principle is easy to understand and simple to follow. But, identifying the distinct interfaces can be challenging to get the right role segregation. The Interface Segregation Principle a very powerful concept to master when developing Java applications.

If you have liked this concept and understood this story you might like Command Patterns which I wrote in the past another behavioral design pattern and is part of the GoF‘s formal list of design patterns. This pattern intends to encapsulate in an object all the data required for performing a given action (command)


Articles from blogs I follow around the net

powerctl: A small case study in Hare for systems programming

powerctl is a little weekend project I put together to provide a simple tool for managing power states on Linux. I had previously put my laptop into suspend with a basic “echo mem | doas tee /sys/power/state”, but this leaves a lot to be desired. I have to u…

via Drew DeVault's blog August 28, 2022

United States v. Microsoft Corp exhibits

Links to exhibits from the Microsoft anti-trust case, with a bit of info on each link. Projection of PC marketshare Share of new browser users Share of the browser market, grouped by major ISP, 3 month moving average Share of the browser market, grouped by ma…

via danluu.com August 24, 2022

Status update, August 2022

Hi all! This month I’ve been pondering offline-first apps. The online aspect of modern apps is an important feature for many use-cases: it enables collaboration between multiple people and seamless transition between devices (e.g. I often switch between my pe…

via emersion August 14, 2022

Generated by openring

© Copyright 2021-2022. Rakesh Mothukuri