Skip to main content

Interface Segregation Principle (ISP)

What is the Interface Segregation Principle?​

You: Hey Shubh, can you explain the Interface Segregation Principle to me?

Shubh: Sure! The Interface Segregation Principle (ISP) is one of the SOLID principles of object-oriented design. It suggests that no client should be forced to implement interfaces they don't use. Instead of having a large, general-purpose interface, it's better to have multiple smaller, more specific interfaces.

Example: Violation of ISP (Bad Approach)​

Let's look at an example where the Interface Segregation Principle is violated:

Employee.java
public interface Employee {
void washDishes();
void cookFood();
void serveFood();
}
Chef.java
public class Chef implements Employee {
@Override
public void washDishes() {
System.out.println("Chef cannot wash dishes");
}

@Override
public void cookFood() {
System.out.println("Chef is cooking the food");
}

@Override
public void serveFood() {
System.out.println("Chef cannot serve the food");
}
}
DishWasher.java
public class DishWasher implements Employee {
@Override
public void washDishes() {
System.out.println("Dishwasher is washing the dishes");
}

@Override
public void cookFood() {
System.out.println("Dishwasher cannot cook food");
}

@Override
public void serveFood() {
System.out.println("Dishwasher cannot serve food");
}
}
Waiter.java
public class Waiter implements Employee {
@Override
public void washDishes() {
System.out.println("Waiter cannot wash dishes");
}

@Override
public void cookFood() {
System.out.println("Waiter cannot cook food");
}

@Override
public void serveFood() {
System.out.println("Waiter is serving the food");
}
}
Main.java
public class Main {
public static void main(String[] args) {
Employee emp = new Chef();
emp.cookFood();
emp.serveFood();
emp.washDishes();
}
}

You: I see that the classes Chef, DishWasher, and Waiter all implement the Employee interface. What's wrong with this approach?

Shubh: The problem here is that the Employee interface has methods that are not relevant to all types of employees. For example, a Chef doesn't wash dishes or serve food, but because of this interface, the Chef class must implement these methods. This approach forces classes to implement methods they don't need, leading to bloated and inefficient code.

A Better Approach: Applying the Interface Segregation Principle​

To adhere to ISP, we should create several smaller, more specific interfaces rather than one large interface with many methods. This way, classes only need to implement the methods that are relevant to them.

You: How would we do that?

Shubh: Let’s refactor the code by breaking down the Employee interface into more specific interfaces:

ChefInterface.java
public interface ChefInterface {
void cookFood();
}
Chef.java
public class Chef implements ChefInterface {
@Override
public void cookFood() {
System.out.println("Chef is cooking the food");
}
}
DishWasherInterface.java
public interface DishWasherInterface {
void washDishes();
}
DishWasher.java
public class DishWasher implements DishWasherInterface {
@Override
public void washDishes() {
System.out.println("Dishwasher is washing the dishes");
}
}
WaiterInterface.java
public interface WaiterInterface {
void serveFood();
}
Waiter.java
public class Waiter implements WaiterInterface {
@Override
public void serveFood() {
System.out.println("Waiter is serving the food");
}
}
Main.java
public class Main {
public static void main(String[] args) {
ChefInterface chef = new Chef();
chef.cookFood();

WaiterInterface waiter = new Waiter();
waiter.serveFood();

DishWasherInterface dishWasher = new DishWasher();
dishWasher.washDishes();
}
}

You: Now each class only implements the interface that defines the methods it actually uses. This seems much cleaner.

Shubh: Exactly! By breaking down the Employee interface into smaller, more specific interfaces, we ensure that each class only deals with methods relevant to its role. This adheres to the Interface Segregation Principle, resulting in cleaner, more maintainable, and efficient code.