CodeOath
← All posts
Architecture & Patterns80 min total · 26 parts

ACID, SOLID, and Common Design Patterns: A Software Design Reference

Contents — Part 10 of 26: Interface Segregation Principle
Part 10 of 26 · ~1 min

Interface Segregation Principle

Don't force a class to depend on methods it doesn't use. A large interface bundling unrelated capabilities forces every implementer to either genuinely support all of them, or fake support for the ones it doesn't need — both bad outcomes.

// Violates ISP — RobotWorker has no meaningful way to implement Eat()
// or TakeBreak(), but the interface forces it to have some implementation.
public interface IWorker
{
    void Work();
    void Eat();
    void TakeBreak();
}

public class RobotWorker : IWorker
{
    public void Work() { /* real implementation */ }
    public void Eat() => throw new NotSupportedException(); // a lie the compiler can't catch
    public void TakeBreak() => throw new NotSupportedException();
}
// Segregated into focused interfaces — implement only what applies.
public interface IWorkable { void Work(); }
public interface IFeedable { void Eat(); }
public interface IRestable { void TakeBreak(); }

public class HumanWorker : IWorkable, IFeedable, IRestable
{
    public void Work() { }
    public void Eat() { }
    public void TakeBreak() { }
}

public class RobotWorker : IWorkable
{
    public void Work() { } // no forced implementation of methods that don't apply
}

The NotSupportedException in the first version is the concrete symptom to watch for in real code review — any override whose entire body is "throw, because this doesn't actually apply to me" is a strong signal the interface it's implementing is too broad and should be split.