DevExpress Newletter 43: Message from the CTO

2 March 2011

This time we’re on to the fourth letter of the SOLID principles.

The I in SOLID - The Interface Segregation Principle

Let's continue our discussion of the SOLID principles. Today we'll look at the I in SOLID: the Interface Segregation Principle.

This can be expressed as: classes that implement interfaces should not be forced to implement methods they do not use. Another way of putting it is: use small interfaces, not fat ones.

Let's illustrate this with an example that I'd like to say is fictional, but probably isn't. In fact, I wrote such an example way back when I was writing Delphi code for a living. Suppose we create a Stream interface that defines methods to reset the stream at the start, and to read and write data into/from a buffer.

interface Stream {
  void Reset();
  void Read(...);
  void Write(...);
}

Once we have the interface, it's easy work to create a class that implements the interface for a memory stream, for example, or a file stream. Indeed many libraries implement such a structure.

However, consider instead a stream for a read-only device, say a communications socket or a read-only file. The reset and read methods are easy enough to write, but what about the write method? It doesn't really apply at all to this scenario. In fact all we can do is to write the method to throw an exception.

Ditto for a write-only stream (a printer port, for example). There is no reason to have either reset or read in this scenario.

What's happened is that the Stream interface is too "fat". A class that implements an interface must implement all methods provided by that interface; no exceptions, even when it doesn't make sense. We find ourselves throwing NotImplementedExceptions and have the feeling that things aren't right. Well, our feelings are correct: things aren't right at all.

What we should do instead is to define ReadableStream and a WritableStream interfaces and have our read/write concrete stream classes implement them both. Our read-only streams need only implement the ReadableStream and our write-only streams the WritableStream interface.

interface ReadableStream {
  void Reset();
  void Read(...);
}

interface WritableStream {
  void Write(...);
}

So, reconsider your interfaces. Are they too fat? Maybe you could be violating the Interface Segregation Principle.

[UPDATE: You can watch the video here.]

Not much more to say about this, but that the .NET Framework is full of good interfaces according to this principle. Take IDisposable as a canonical example: the minimal interface at just one method. And the whole streaming interfaces go much further than I’ve demonstrated here.

Remember, the whole series is based on papers written by Uncle Bob (Robert C Martin). Click here for the PDF on ISP.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.