Previous post in this series:
SOLID – (LSP) The Liskov Substitution Principle

CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE.

When clients are forced to depend upon interfaces that they don’t use, then those clients are subject to changes to those interfaces. This results in an inadvertent coupling between all the clients. Said another way, when a client depends upon a class that contains interfaces that the client does not use, but that other clients do use, then the client will be affected by the changes that those clients force upon the class. We would like to avoid such couplings where possible, and so we want to separate the interfaces where possible.

The Interface Segregation Principle, Robert C. Martin

Unlike the other posts in this series I’m not going to include any code. It’s a theory only post. Uncle Bob’s material on the ISP, while good at explaining the ISP, has what I consider pretty poor code examples. In his other papers I understand how the examples of bad code could come about. For some reason I just find it hard to wrap my head around the bad code he demonstrates for the ISP. In his explanation of the bad code he even goes on to say, “Although this solution is common, it is not without problems.” But his example is so bad, how could it be common in OOD? Read his paper and tell me if you don’t agree with me. Regardless, know that even if the example is poor, the reasoning and purpose of the ISP is solid. (See what I did there? 🙂

The first thing to note on Uncle Bob’s quote above is that by interfaces Uncle Bob doesn’t mean only “interface” as in the C# keyword whereby we define a contract that the class will adhere to but also any base or abstract classes we extend from. Naturally than, if there is some base class we extend from that extends from another class (ad nauseam) that extends from some abstract class we are getting a lot of functionality but also a lot of overhead with each class. That is not to say that this is invalid but at each extension you have to understand that you are adding to the class and may be violating the SRP, the OCP and the LSP.

What the ISP is trying to correct is the injection of so much functionality into a single class that you end up with impacting the internal code causing the class to have to implement changes that override the original purpose of the class. So now, you may not have only violated the SRP but you risk violating the LSP.

This principle deals with the disadvantages of “fat” interfaces. Classes that have “fat” interfaces are classes whose interfaces are not cohesive. In other words, the interfaces of the class can be broken up into groups of member functions. Each group serves a different set of clients. Thus some clients use one group of member functions and other clients use the other groups.

The ISP acknowledges that there are objects that require non-cohesive interfaces; however it suggest that clients should not know about them as a single class. Instead, clients should know about abstract base classes that have cohesive interfaces. Some languages refer to these abstract base classes as “interfaces”, “protocols” or “signatures”.

The Interface Segregation Principle, Robert C. Martin

What we’re doing is trying to prevent so much downward pressure upon the purpose of a class from the clients that use it we end up making the class worthless because to make any changes to it would completely break any clients using it. Here’s the thing about SOLID, its purpose is to make your job easier. That may not be obvious. There is a lot of concepts here built from Uncle Bob’s experience (concepts that have proven useful in my own experience). What this means is that by extension, if you adhere to these concepts, than if I’m ever on a project your on, my job will be easier. All this is about trying to make our jobs easier.

So how do we prevent downward pressure? Well, the first way is the “Adapter” pattern (aka a wrapper). There is a good example in C# of the adapter pattern on wiki. The purpose there is essentially to modify a class in such a way that we as a client can use it without impacting any other clients that use it. Understand that this is huge. We get any specialization that we need out of the class without having to worry about the LSP and the OCP.

The second way is to simply judiciously apply interfaces. Where we need them, if it makes sense, extend from a class and implement the interface. There is nothing wrong with this. There are perfectly valid instances where we need separate interfaces.

Finally, Uncle Bob recommends the above, but with multiple inheritance, an option not available to us in C#.

If you’re dying for some sort of source code (though I would recommend anyways) read Uncle Bob’s source material this post is based on.

Leave a Reply

Your email address will not be published. Required fields are marked *

FormatException

928 East Plymouth Drive Asbury Park, NJ 07712