Lecture thumbnail 0:00 / 0:00 All right.
So the next principle, which I want to show you, is the interface segregation principle.
And for this one, I’m actually going to do a bit of a synthetic example because essentially the interface
segregation principle is something that you are likely to encounter in the real world where you just
building interfaces which are too large.
And the idea is quite simple that your interfaces should be segregated so that nobody who implements
your interface has to implement functions which they don’t actually need.
So let me give you an example.
Let’s suppose you have a document and you want to do different things with the document, so you try
to emulate some sort of printer or scanner.
But there is also this thing called the multifunction printer, which does both the printing, the scanning
as well as the photocopying as well.
So you decide, oh, I’ll make an interface for everything.
So you build one big interface called I machine.
And this I machine interface does all things so it can print the document.
So it can print the document document as soon as I learn how to spell that is print the document D and
it can also scan the document.
So it can scan and you can maybe fax the document as well.
So you build this kind of interface and this interface works just fine so long as you are actually working
with a multifunction printer.
So if you have a multifunction printer, then everything is fine because you implement this AI machine
interface, you go ahead and you implement the members and then you can do something for each of the
members because the thing can in fact print it can in fact scan documents and it can also fax document,
for example.
So this is okay.
But then you go ahead and you decide to make just a good old fashioned printer, old fashioned printer.
It cannot scan, it cannot fax documents, anything like that.
So the problem is that you’ve only got this one big interface with lots of responsibilities attached
to it.
So what do you do?
I mean, you have to implement this interface, so you implement the interface machine, you implement
the missing members.
And certainly implementing the print function is obvious enough.
You have a printer, so you implement print.
But now the question is, well, what do you do about the scanning and the faxing?
Do you throw an exception?
Do you do a no op?
Do you maybe output some message that this operation is not supported?
I mean, the operation is kind of undefined a little bit, especially for the consumers of your API.
So you would have to really document that your old fashioned printer, even though it implements the
eye machine interface, it does in fact only supply the implementation of print and does not supply
the implementations of scan and fax.
So that’s a bit of a problem.
And that is where the interface segregation principle comes in.
So the idea is to make sure that people don’t pay for things they don’t need.
And this means that if you don’t need the scanning and the faxing, then those things should be separable
somehow.
And instead of having one big interface, you should have lots of smaller interfaces which are more
atomic, shall we say, in the sense that they are kind of self-contained and they cover a particular
concern.
So what you would do in this case is of course you’d make a lot of smaller interfaces.
So for the printing you would have an eye printer interface where you would have the print function.
So this would work on a document.
And similarly for the scanning, for example, you would have the eye scanner interface and this would
have the void scan function again on on a document or into a document in this case.
And then of course, if you want to start implementing these functions, then you can and there are
different ways of doing it.
So one is if you are making a photocopier, for example, then you might want to implement just both
of these interfaces.
So if you have a photocopier, for example, then you might want to have the eye printer interface and
also the eye scanner interface.
And then you simply implement all the missing members and you actually provide the appropriate implementation.
Or of course if you do want a higher level interface as well, like a kind of eye multifunction device
interface, you can have it as well because interfaces can inherit from interfaces.
So you can have an eye multi-function device, which is actually an interface which is both an eye scanner,
eye printer, eye printer and other things as well.
So you can have other interfaces here.
And then of course when it comes to actually implementing this interface, once again, you have different
options of doing it.
So one way would be if you have a class called Multifunction Machine of some kind, you can just go
ahead and you can implement this eye multifunction device interface.
So that’s one approach.
And how you actually implement this is completely up to you because, for example, if you already have
the implementations of a printer and a scanner and you’re saying that the multifunction device is simply
the joining of those.
Two classes, concrete classes that you already have.
Then you can do delegation.
And in this case, you would implement the missing members.
Or rather, you might not implement the missing members.
What you can do instead is you can suppose you already have a printer in the scanner implementation.
Some way you can have, for example, an AI printer called printer and an AI scanner called Scanner.
And what you can do now, thanks to the magic of Resharper, is first of all, you can make a constructor
which actually initializes both of these.
And then of course, what you can do is you can delegate the calls to each of the interface methods
of AI multifunction device.
You can delegate them to the printer and the scanner respectively.
It’s the decorator pattern in actual fact.
So what you can do is you can go in here into the generate menu.
You can choose delegating members and just select all the members.
And so print will be delegated to printer and scan will be delegated to scanner.
So here it is.
So we’ve auto generated the implementations of the AI multifunction device interface and we’re actually
delegating the calls to the calls of the inner printer and scanner variables.
A classic example of the decorator pattern.
So this is the decorator.
So this is the interface segregation principle, a basic idea that if you have an interface which includes
too much stuff, then just break it apart into smaller interfaces.
Play Play Play Play Stop Play Play