The Interface Segregation Principle (ISP) says that many client specific interfaces are better than one general purpose interface. Why is this important?
ISP states that:
Clients should not be forced to depend on methods that they do not use.
ISP relates to important characteristics - cohesion and coupling.
Ideally your components must be highly tailored. It improves code robustness and maintainability.
Enforcing ISP gives you following bonuses:
- High cohesion - better understandability, robustness
- Low coupling - better maintainability, high resistance to changes
If you want to learn more about software design principles, get a copy of Agile Software Development, Principles, Patterns, and Practices book.
The interface segregation is the “I” on the SOLID principle, before digging too deep with the first, let’s explain what’s does the latter mean.
SOLID can be considered a set of best practices and recommendations made by experts (meaning they have been proved before) in order to provide a reliable foundation in how we design applications. These practices strive to make easier to maintain, extend, adapt and scale our applications.
Why should I care about SOLID programming?
First of all, you have to realize you are not going to be forever where you are. If we use standards and well known architectures, we can be sure that our code will be easy to maintain by other developers that come after us, and I’m sure you wouldn’t want to deal with the task of fixing a code that didn’t applied any known methodology as it would be very hard to understand it.
The interface segregation principle.
Know that we know what the SOLID principles are we can get into more detail about the Interface Segregation principle, but what exactly does the interface segregation says?
“Clients should not be forced to implement unnecessary methods which they will not use”
This means that sometimes we tend to make interfaces with a lot of methods, which can be good to an extent, however this can easily abused, and we can end up with classes that implement empty or useless methods which of course adds extra code and burden to our apps. Imagine you are declaring a lot of methods in single interface, if you like visual aids a class that is implementing an interface but that is really needing a couple of methods of it would look like this:
In the other hand, if you properly apply the interface segregation and split your interface in smaller subsets you can me sure to implement those that are only needed:
See! Is way better! Enforcing this principle will allow you to have low coupling which aids to a better maintainability and high resistance to changes. So you can really leverage the usage of interfaces and implementing the methods when you really should. Now let’s review a less abstract example, say you declared an interface called Reportable
public interface Reportable {
void printPDF();
void printWord();
void printExcel();
void printPPT();
void printHTML();
}
And you have a client that will only to export some data in Excel format, you can implement the interface, but would you only have to implement the excel method? The answer is no, you will have to code the implementation for all the methods even if you are not going to use them, this can cause a lot of junk code hence making the code hard to maintain..
Remember keep it simple and don’t repeat yourself and you will find that you are already using this principle without knowing.
It simplifies the interface that any one client will use and removes dependencies that they might otherwise develop on parts of the interface that they don't need.
One reason is that having many interfaces with a minimal amount of methods for each one makes it easier to implement each interface and to implement them correctly. A large interface can be unruly. Also, using a focused interface in a scenario makes the code more maintanable because you can see which facet of the object is being used (e.g., an IComparable interface lets you know that the object is only being used for comparisons in the given scenario).
This principle primarily serves twin purposes
To make the code more readable and manageable.
Promotes single responsibility for classes ( high cohesion ). Ofcourse why should a class have a method that has no behavioural impact ? Why not just remove it. Thats what ISP is about
There are few questions that a designer must ask with concerns to ISP
- What does one achieve with ISP
- How to I analyse an already existing code for any ISP violations
To take this discussion further, I must also add that this principle isn't a 'principle' in the strictest sense, because under certain circumstances, applying ISP to the design, instead of promoting readability, might make the object structure unreadable and cluttered with unnecessary code. You may well observe this in the java.awt.event package
More at my blog: http://design-principle-pattern.blogspot.in/2013/12/interface-segregation-principle.html
ISP is important.
Basic idea of ISP : Client should not be forced to depend on methods it does not use.
This principle seems to be more logical. Ideally client should not implement the methods, which are not used by the client.
Refer to below SE question for code example:
Interface Segregation Principle- Program to an interface
Advantages:
Flexibility : In absence of ISP, you have one Generic FAT interface and many classes implementing it. Assume that you had 1 interface and 50 classes. If there is a change in interface, all 50 classes have to change their implementation.
With ISP, you will divide generic FAT interface into fine granular small interfaces. If there is a change in small granular interface, only the classes implementing that interface will be affected.
Maintainability and Ease of use: Since changes are limited to fine granular interface instead of generic FACT interface, code maintenance is easier. Unrelated code is no longer part of implementation classes.
Robert Martin's paper on the subject gives an explanation that's mentioned less often:
The backwards force applied by clients upon interfaces.
If two classes depend directly on two different methods of a third class, it increases the likelihood that changes to either of the first two classes will affect the other.
Suppose we have three classes: Red
, Green
, and Blue
.
Red
and Green
both depend Blue
, but each depends on a different method. That means that Red
depends on one method of Blue
but doesn't use the other method. Likewise, Green
depends on Blue
, but only uses one method, not the other.
The violation of the principle is in Red
and Green
because each depends on a class - Blue
- but doesn't use at least one of its methods.
What problem does this potentially create?
- I need to change
Red
, and I also changeBlue
to accommodate the needs ofRed
. - I haven't changed the specific method within
Blue
thatGreen
depends on, but nonetheless,Green
depends onBlue
and I have changedBlue
, which could still impactGreen
. - Therefore, my changes to
Red
have the potential to impactBlue
because they've led me to change a class that both depend on.
That's the "backwards force." We sometimes change a class because of the needs of its clients. If that class has different clients that use it for different things, we risk impacting them.
As stated, the simple definition of the Interface Segregation Principle is:
no client should be forced to depend on methods it does not use.
Between that and the above point from Robert Martin's paper, it's apparent that many explanations of the ISP are in fact talking about other principles.
- Classes or interfaces with lots of methods are undesirable, but not specifically because of the ISP. They might violate Single Responsibility. But the ISP violation is not in the big interface or big class - it's in the classes that depend on on the big interface if they don't use all of its methods. If they use all of the methods it still sounds messy, but that has nothing to do with the ISP.
- Classes that implement an interface but throw exceptions for certain methods are bad, but that's not the ISP, either. The ISP is about classes that depend on interfaces, not classes that implement interfaces.
If we Google "interface segregation", most of the top results that include code samples demonstrate classes that don't fully implement interfaces, which is not the point of the ISP. Some even restate the principle:
The Interface Segregation Principle states that clients should not be forced to implement interfaces they don't use
...but that is not the principle. The defining paper mentions such concerns as a side-effect of violating the ISP, but indicates that they are Liskov Substitution violations.
Moreover, each time a new interface is added to the base class, that interface must be implemented (or allowed to default) in derived classes. Indeed, an associated practice is to add these interfaces to the base class as nil virtual functions rather than pure virtual functions; specifically so that derived classes are not burdened with the need to implement them. As we learned in the second article of this column, such a practice violates the Liskov Substitution Principle (LSP), leading to maintenance and reusability problems.
What's more, to say that a client should not implement methods it does not use doesn't even make sense. The clients of an interface do not implement its methods.
I don't mean to pompously cite the paper as if it's holy writ or something. But if we're going to use the name of the principle described in the article (the name of the article itself) then we should also consider the actual definition and explanation contained in that article.
来源:https://stackoverflow.com/questions/58988/what-is-the-reasoning-behind-the-interface-segregation-principle