Goodbye monolithic interfaces – the Interface Segregation Principle
“No client should be forced to depend on methods it does not use” (more wikipedia)
This refers to a situation where an interface has more methods than is good for it. If you've got too many methods then using that interface on something new starts to get difficult, you either have to implement all of the methods stated in the interface (whether you need them or not), or end up putting dummy code / NotImplemented exceptions in there, neither of which are a good idea. As an example, we've got a Person class below with a matching interface:
public interface IPerson
{
void Sleep();
void Dance();
}
public class Person : IPerson
{
public void Sleep()
{
Console.WriteLine("Sleeping");
}
public void Dance()
{
Console.WriteLine("Dancing");
}
}
Then we create a place for the people to dance in:
public class Disco
{
private IEnumerable<IPerson> _dancers;
public Disco(List<IPerson> dancers)
{
_dancers = dancers;
}
public void TurnOnMusic()
{
foreach (IPerson d in _dancers)
{
d.Dance();
}
}
}
So we've got a disco that we can create with a list of people and when the music is turned on they all start to dance. Let’s just ignore the fact that they’ll never stop dancing, they’ll be ok.
If we never use that IPerson interface again and nothing else will Sleep or Dance then there are no problems. But what if someone took along one of those dancing flowers to the disco. It’s not a person, but it can still dance! Bah, if only we’d applied the ISP we could add anything capable of dancing to our disco and have it dance forever too!
Lets make some changes. First we’ll split up the interface, IPerson becomes:
public interface ISleeper
{
void Sleep();
}
public interface IDancer
{
void Dance();
}
Now we can just use those interfaces for the person:
public class Person : ISleeper, IDancer
{
…No other changes here`
And create the dancing flower (It’s going to dance but not sleep):
public class DancingFlower : IDancer
{
public void Dance()
{
Console.WriteLine("Dance flower dance!");
}
}
Now for a quick change to the disco:
public class Disco
{
private IEnumerable<IDancer> _dancers;
public Disco(IEnumerable<IDancer> dancers)
{
_dancers = dancers;
}
public void TurnOnMusic()
{
foreach (IDancer d in _dancers)
{
d.Dance();
}
}
}`
Now we can take anything that dances to the disco and have it dance, whether it’s a person, a flower, a dog, you name it as long as it’s an IDancer it can go and party! (and never stop)
*No dancers were harmed in the making of this blog.
Got a comment or correction (I’m not perfect) for this post? Please leave a comment below.
Subscribe to Gavin Johnson-Lynn
Get the latest posts delivered right to your inbox