Interface Segregation Principle

Is Your Interface Too Fat?

SOLID OOP Wednesday, May 21, 2014

The interface segregation principles states that an interface should not force classes to implement stuff that it doesn't need. For example, let's say we have a repository interface:

public interface IRepository<T>
{
  T Get(int id);
  List<T> GetPage(int page);
  List<T> GetSillyData();
}

Something is right, is it? Not all repositories are going to need to implement GetSillyData but they'll have to (probably throwing a NotSupportedException), otherwise the project won't compile.

This is a case of a polluted interface. If there are repositories that may need to retrieve silly data, we could and should have those classes defined as such:

public interface IRepository<T>
{
  T Get(int id);
  List<T> GetPage(int page);
}

public interface ISilly<T>
{
  List<T> GetSillyData();
}

public class OneOfAKindRepository : IRepository<T>, ISilly<T>
{
  public T Get(int id)
  {
    // implementation
  }

  public List<T> GetPage(int page)
  {
    // implementation
  }
  
  public List<T> GetSillyData()
  {
    // implementation
  }
}

If you happen to have many cases which you have silly repositories, you could always create an ISillyRepository<T> that would contain both interface definitions still leaving you with the possibility to use IRepository<T> or ISilly<T> separetly.

public ISillyRepository<T> : IRepository<T>, ISilly<T>
{
}

The key question here is to ask: Will every single implementation need all of these members?