Skip to content

Interface Segregation

Definition

Interface Segregation Definition


Violation Example

// BAD: Fat interface - forces unnecessary implementations
public interface Worker {
    void work();
    void eat();
    void sleep();
    void attendMeeting();
    void writeReport();
    void reviewCode();
}

// Human worker - uses all methods
public class Developer implements Worker {
    public void work() { /* coding */ }
    public void eat() { /* lunch break */ }
    public void sleep() { /* rest */ }
    public void attendMeeting() { /* standup */ }
    public void writeReport() { /* status update */ }
    public void reviewCode() { /* PR review */ }
}

// Robot worker - forced to implement irrelevant methods!
public class RobotWorker implements Worker {
    public void work() { /* performs task */ }

    public void eat() {
        throw new UnsupportedOperationException(); // Robots don't eat!
    }

    public void sleep() {
        throw new UnsupportedOperationException(); // Robots don't sleep!
    }

    public void attendMeeting() {
        throw new UnsupportedOperationException();
    }

    public void writeReport() { /* can generate report */ }

    public void reviewCode() {
        throw new UnsupportedOperationException();
    }
}

// Problems:
// - RobotWorker has meaningless methods
// - Client code might call inapplicable methods
// - Changes to eat() affect RobotWorker unnecessarily

Proper Implementation

// GOOD: Segregated interfaces

// Core work interface
public interface Workable {
    void work();
}

// Human-specific needs
public interface Feedable {
    void eat();
}

public interface Restable {
    void sleep();
}

// Role-specific behaviors
public interface MeetingAttendee {
    void attendMeeting();
}

public interface ReportWriter {
    void writeReport();
}

public interface CodeReviewer {
    void reviewCode();
}

// Developer implements only what they need
public class Developer implements Workable, Feedable, Restable,
                                  MeetingAttendee, ReportWriter, CodeReviewer {
    public void work() { /* coding */ }
    public void eat() { /* lunch */ }
    public void sleep() { /* rest */ }
    public void attendMeeting() { /* standup */ }
    public void writeReport() { /* status */ }
    public void reviewCode() { /* PR review */ }
}

// Robot only implements applicable interfaces
public class RobotWorker implements Workable, ReportWriter {
    public void work() { /* performs task */ }
    public void writeReport() { /* generates report */ }
}

// Client code depends only on what it needs
public class TaskScheduler {
    public void assignWork(Workable worker) {
        worker.work();  // Works with any worker
    }
}

public class LunchOrganizer {
    public void scheduleLunch(Feedable person) {
        person.eat();  // Only accepts those who eat
    }
}

Real-World Example

// BAD: Repository with too many methods
public interface Repository<T> {
    T findById(Long id);
    List<T> findAll();
    T save(T entity);
    void delete(T entity);
    void deleteById(Long id);
    List<T> findByField(String field, Object value);
    Page<T> findAll(Pageable pageable);
    long count();
    boolean existsById(Long id);
    List<T> saveAll(List<T> entities);
    void deleteAll();
    // ... 20 more methods
}

// Some services only need to read
public class ReportService {
    private Repository<Order> repo;  // Has delete access it shouldn't!
}

// GOOD: Segregated repositories
public interface ReadRepository<T> {
    Optional<T> findById(Long id);
    List<T> findAll();
    boolean existsById(Long id);
    long count();
}

public interface WriteRepository<T> {
    T save(T entity);
    List<T> saveAll(List<T> entities);
}

public interface DeleteRepository<T> {
    void delete(T entity);
    void deleteById(Long id);
    void deleteAll();
}

// Combine as needed
public interface CrudRepository<T> extends
    ReadRepository<T>, WriteRepository<T>, DeleteRepository<T> {
}

// Services depend on minimal interface
public class ReportService {
    private ReadRepository<Order> repo;  // Can only read
}

public class OrderService {
    private CrudRepository<Order> repo;  // Full access
}

Interface Composition

Interface Composition


Signs of ISP Violation

ISP Violations


Applying ISP

How to Apply ISP


Tips & Tricks

ISP Tips