Interface Segregation Principle
IntermediateClients should not be forced to depend on methods they do not use — prefer many small, role-specific interfaces over one fat interface.
Overview
ISP (Robert Martin) addresses the problem of "fat" interfaces that force implementing classes to provide stub implementations for methods they do not need. When a class implements a fat interface, changing an unrelated method forces the class to recompile even though it does not use that method. The fix is to split fat interfaces into role interfaces (ISP) — each interface represents exactly one role or capability. Java's Comparable vs Comparator, Readable vs Writeable vs Closeable streams, and Spring Data's CrudRepository vs JpaRepository hierarchy all demonstrate ISP.
Fat Interface and Role Interface Split
A Worker interface with work(), eat(), and sleep() forces Robot to implement eat() and sleep() with empty stubs — robots do not eat or sleep. Split into focused role interfaces.
// ❌ ISP Violation: fat interface
public interface Worker {
void work();
void eat(); // not applicable to robots
void sleep(); // not applicable to robots
void attendMeeting();
}
public class HumanWorker implements Worker {
@Override public void work() { System.out.println("Human working"); }
@Override public void eat() { System.out.println("Human eating"); }
@Override public void sleep() { System.out.println("Human sleeping"); }
@Override public void attendMeeting() { System.out.println("Human in meeting"); }
}
public class RobotWorker implements Worker {
@Override public void work() { System.out.println("Robot working"); }
@Override public void eat() { throw new UnsupportedOperationException("Robots don't eat!"); }
@Override public void sleep() { throw new UnsupportedOperationException("Robots don't sleep!"); }
@Override public void attendMeeting() { /* robots attend via video? */ }
}
// ✅ ISP Fix: role interfaces
public interface Workable { void work(); }
public interface Feedable { void eat(); }
public interface Restable { void sleep(); }
public interface MeetingCapable { void attendMeeting(); }
// Human implements all roles it needs
public class HumanWorker implements Workable, Feedable, Restable, MeetingCapable {
@Override public void work() { System.out.println("Human working"); }
@Override public void eat() { System.out.println("Human eating"); }
@Override public void sleep() { System.out.println("Human sleeping"); }
@Override public void attendMeeting() { System.out.println("Human in meeting"); }
}
// Robot only implements what it can do — no stubs, no exceptions
public class RobotWorker implements Workable, MeetingCapable {
@Override public void work() { System.out.println("Robot working"); }
@Override public void attendMeeting() { System.out.println("Robot attending via stream"); }
}
// Client depends only on the role it needs
public class WorkScheduler {
private final List<Workable> workers;
public WorkScheduler(List<Workable> workers) { this.workers = workers; }
public void startWork() { workers.forEach(Workable::work); }
// Does not care if worker is Human or Robot — depends only on Workable
}ISP in Spring Data Repository
Spring Data's repository hierarchy is a textbook ISP example. Clients that only need basic CRUD depend on CrudRepository; clients needing JPA-specific features depend on JpaRepository.
// Spring Data repository hierarchy — ISP in practice
// CrudRepository: save, findById, findAll, delete, count
// PagingAndSortingRepository extends CrudRepository: findAll(Pageable)
// JpaRepository extends PagingAndSortingRepository: flush, saveAndFlush, deleteInBatch
// Service that only needs basic CRUD — depends on minimal interface
public interface CourseRepository extends CrudRepository<Course, String> {
Optional<Course> findByTitle(String title);
// Does NOT depend on JPA-specific methods — ISP compliant
}
// Service that needs pagination — depends on the right interface
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
Page<User> findByStatus(String status, Pageable pageable);
}
// Service that needs flush/batch delete — depends on JPA-specific interface
public interface AuditLogRepository extends JpaRepository<AuditLog, Long> {
void deleteByCreatedAtBefore(LocalDateTime cutoff);
}
// ISP benefit: if JpaRepository adds a new method, only classes
// that extend JpaRepository are affected — other repositories are untouched.Key Points to Remember
- 1Fat interfaces force implementing classes to provide empty/unsupported stubs — violating ISP.
- 2Split fat interfaces into role interfaces — each interface has one cohesive purpose.
- 3Java's Readable, Writable, and Closeable are role interfaces (ISP in java.io).
- 4Spring Data CrudRepository → PagingAndSortingRepository → JpaRepository is a graduated ISP hierarchy.
- 5ISP is the interface-level application of SRP — both are about cohesion.
Interview Questions
Sign in to ask AriaWhat is an ISP violation? Give an example.
How does Spring Data's Repository hierarchy demonstrate ISP?
What is the difference between ISP and SRP?
When is it acceptable to have a larger interface?
Ask Aria about Interface Segregation Principle
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.