The Interface Segregation Principle (ISP) in SOLID.
The Interface Segregation Principle (ISP) in Java states that a class should not be forced to implement methods it does not use.
Instead, interfaces should be split into smaller, more specific ones so that implementing classes only need to implement methods that are relevant to them.
This principle is especially useful in preventing “fat interfaces” (interfaces with too many unrelated methods).
The Interface Segregation Principle (ISP) in Java states that a class should not be forced to implement methods it does not use. Instead, interfaces should be split into smaller, more specific ones so that implementing classes only need to implement methods that are relevant to them.
This principle is especially useful in preventing “fat interfaces” (interfaces with too many unrelated methods).
Let’s look at a real world scenario.
In a school normally only Teachers teach and they don’t monitor other teachers.
Principle is not teaching students and his main job is monither the teachers.
So if we put void teach(); and void monitorTeachers(); in an one genetal interfaces their will be below problems.
Problems:
Both Teacher and Principal are forced to implement methods they don’t use (monitorTeachers() for Teacher and teach() for Principal).
Adding new responsibilities to the interface (e.g., conductMeeting()) will force all implementing classes to provide dummy implementations even if they don’t need it.
Violation of ISP: The interface is too broad and combines unrelated responsibilities.
An Example of violation
public interface SchoolMember {
// A fat interface that combines unrelated responsibilities
void teach();
void monitorTeachers();
}
public class Teacher implements SchoolMember{
@Override
public void teach() {
System.out.println("Teacher is teaching students.");
}
@Override
public void monitorTeachers() {
// Teacher doesn't monitor other teachers, so this method is irrelevant
throw new UnsupportedOperationException("Teacher cannot monitor other teachers.");
}
}
public class Principal implements SchoolMember {
@Override
public void teach() {
// Principal doesn't teach students, so this method is irrelevant
throw new UnsupportedOperationException("Principal does not teach.");
}
@Override
public void monitorTeachers() {
System.out.println("Principal is monitoring teachers.");
}
}
public class MainSchool {
public static void main(String[] args) {
SchoolMember teacher = new Teacher();
SchoolMember principal = new Principal();
teacher.teach(); // Works fine
principal.monitorTeachers(); // Works fine
principal.teach(); // Throws UnsupportedOperationException
teacher.monitorTeachers(); // Throws UnsupportedOperationException
}
}
Output
Teacher is teaching students.
Principal is monitoring teachers.
Exception in thread "main" java.lang.UnsupportedOperationException: Principal does not teach.
at com.sam.oop.Principal.teach(Principal.java:7)
at com.sam.oop.MainSchool.main(MainSchool.java:11)
Process finished with exit code 1
With ISP: A Better Design
To comply with the Interface Segregation Principle, we can split the SchoolMember interface into two smaller, more specific interfaces:
interface Teachable contains methods only belongs to Teachers
interface Monitorable contains methods only belongs to Principle
public interface Teachable {
// Split interfaces for specific responsibilities
void teach();
}
public interface Monitorable {
void monitorTeachers();
}
public class Teacher implements Teachable{
@Override
public void teach() {
System.out.println("Teacher is teaching students.");
}
}
public class Principal implements Monitorable {
@Override
public void monitorTeachers() {
System.out.println("Principle monitor teachers");
}
}
public class MainSchool {
public static void main(String[] args) {
Teachable teacher = new Teacher();
Monitorable principal = new Principal();
teacher.teach(); // Works fine
principal.monitorTeachers(); // Works fine
}
}
Output-
Teacher is teaching students.
Principle monitor teachers
Process finished with exit code 0
Summary of the Improvement:
By splitting the interface, Teacher and Principal are no longer forced to implement irrelevant methods.
This approach adheres to the Interface Segregation Principle by avoiding fat interfaces and ensuring clean, modular design.
Key Takeaways:
Without ISP: The design forces unnecessary checks (try-catch for irrelevant methods).
With ISP: The design is clean, modular, and free from irrelevant method calls. The compiler ensures correctness by restricting the use of unrelated functionality.
Common Misconceptions About ISP (Short Form)
One Interface = One Method:
ISP allows grouping related methods in one interface; splitting unnecessarily causes complexity.
Always Split Interfaces:
Split only when needed. Over-segregation adds unnecessary interfaces.
Applies Only to Large Systems:
ISP is useful in all projects, big or small, to keep code clean and maintainable.
Same as SRP:
SRP applies to classes (one reason to change), while ISP applies to interfaces (focused and relevant methods).
More Interfaces = ISP Compliance:
ISP creates focused interfaces, not necessarily more interfaces.
Only About Splitting Methods:
ISP ensures clients depend only on what they use, avoiding bloated interfaces.
Avoid Interfaces:
ISP refines interfaces but doesn’t discourage their use (maintain abstraction per DIP).
Interface Changes Never Affect Clients:
ISP reduces, but doesn’t eliminate, the impact of interface changes.
Always Leads to Smaller Interfaces:
ISP sometimes results in fewer but better-designed interfaces.
Not Relevant for Small Systems:
ISP is equally beneficial in small projects to prevent technical debt.