Design Patterns: Interface Segregation Principle Explained Practically in C# (The I in SOLID)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
when you're writing code are you doing it right that's the question that worries a lot of people and it should probably at least something that every developer things through design patterns our best practice concepts that we can implement into our code to make it better in some way thinking there's guardrails to keep our codes safe and help us do it right in today's video we're going to look at the fourth entry in the famous solid principle the I stands for interface segregation principle we're gonna dive into what it means how it should change our programming practices and how far we should take it for those of you who don't know me my name is Tim quarry and it's my goal to clear up the confusion and frustration around learning c-sharp because learning software development shouldn't be so hard if that sounded something that would interest you I think you benefit from subscribe to my channel and also join my mailing list my mailing list is where you get exclusive content and insider access you can find a link to join the mailing list in the description below also in that description you'll file link to my blog post on this topic where I include the download links for a source code at the beginning of this video and also a source code at the end so let's start the conversation on the interface segregation principle which we're gonna call isp from now on by looking at some code i could do some nifty powerpoint for you and show you some fun pictures that try and represent the issue but i find it best just to look at this in a practical manner here I have a project that I created in Visual Studio in c-sharp now the principles as video actually apply to any software development language but since this channel focuses primarily on c-sharp that's the language will use the code I have here is rather simple I have a console application that simulates the data structure of a library application and by library I mean a place that lends books and other items not the c-sharp class library project type so as you can see we have our programmed SCS which doesn't do anything yet and really it doesn't have to we may get in a little bit here but the most part is all about our class library we have here one interface right now the IEEE library item and that has a bunch of properties and a few methods then we have four different classes that implement this interface we have the book class with implementation we have the audiobook class the DVD class and the reference book class as well now the problem with its application so far is that it violates ISP so now that we have some code in front of us let's talk about is P is P states that a client should not be forced to depend on interfaces they don't use so let's look at how that plays out our interface is a library item now the book class implements everything so it has a library ID that works title author pages checkout duration and days who the borrower is if there is one when when the borrowed date was and then three methods check it out check it in and get due dates which sounds great all of these apply to a book and probably if your library application was old enough or small enough to start with that's all you really had was books that's usually the primary thing you think of when libraries is lending books but they do so much more so the next Ayano come up is audiobooks well an audio book has a title and author but pages on audio book doesn't have pages now you could say well the original book had a number of pages true that's not this okay this is this would be tapes or CDs or mp3s or something that nature therefore that's not really something that we need and so I said two negative one because we don't want it to reflect an actual value and we actually have this additional property called run time it's yeah it's kind of important for an audiobook how long is it but all the rest is tough for the applies now another implementation would be a reference book think of these as the very large dictionaries that you can't check out or mail an encyclopedia again you can't check it out so adds all the things of a book but borrower or there's an apply checkout duration in days well you can't have any duration therefore I set a zero but that's not really a effective way of doing things borrower date doesn't apply check out check in and get due date I set them all to throw a new not intimate exception because they don't implement those methods they don't you can't borrow you can't check out you can't check in and you can't get a due date for a book that never leaves a library so that's where a violation again of the interface segregation principle comes into play we're relying on this interface which says you have to have these three methods but they don't really apply neither does this property or this property or this property there's a lot of stuff here that doesn't apply to a reference book then library started allowing DVDs he borrowed well a DVD doesn't have pages it does have a list of actors and does have a runtime minutes so it gets close but it's not the same thing because those pages don't reapply and need it as the author because you're kind of shoehorning something in a try and put something in the author you could say that director but that's not the same thing a director is not the author so these two properties don't really apply but we do have a couple of additional properties we want to add that makes sense for a DVD so we've learned is this interface right here well it gives us all the different parts that a book needs it doesn't really other items audiobooks have something different the dvds has a radically different and the reference book is just so different that really half the stuff doesn't apply and so this would be one monolithic interface but it's not really gonna work well for us and so what is P says is break this down into smaller pieces now if you watch my previous video on LSP the Liskov substitution principle some of stuff's gonna seem really familiar because we're really doing the same thing with interfaces that we did with classes and inheritance in the last video we're gonna break this down into pieces that everyone can agree on that uses them it will kind of make them more modular so let's start off by cutting down this I library item what are the things that are really important and let's move us up here what are things that are really important to a library item well a library ID everything has a library ID that's like that that unique barcode or unique identifier that says this is the identifier for what this particular item is in the library now we also have title down here which I'm not sure why these get moved down but we can move around we have title that reapplies to pretty much everything we can say title is the title with it's the title of a movie the title a book the title an audio book the reference book even other things would have a title so we can keep that author doesn't apply so let's go ahead and comment that out for now borrow date well reference books we're not gonna borrow therefore let's get rid of that the borrower the checkout duration days pages that's a book thing the check in the check out and the get due date those are all borrow items so that's one interface now the I library item that just has two pieces of information the ID from the library and the title that's it now let's create some more interfaces that will further define the different pieces and kind of group them together so let's start by right-click on demo library and say add new item interface and let's call this the let's start iBook so the iBook interface is going to further define a library item so we'll actually inherit from a library item now the book is going to have let's go over here and grab it they'll also have the author information and the pages information so let's move those together and I'll cut them out of here I'll paste them in here and we will uncomment them okay so the iBook now has author and pages as well as what inherits from I library item my library item has library ID and title so now I can get a little more information here about what a book is now we also need to have something for all the borrow information so let's create a interface called I borrow able and make it public I'll come back over to let's close out you get so many tabs open it's just hard to see where everything is let's go over here and grab all of these and cut them out and paste them into I borrow a bowl and uncomment them now we could have I borrow Bowl inherit from either I library em or I book but that's gonna cause some weird conflicts and the reason why is because what about the reference book how we say that's we have a reference book and also a regular book which is borrowing so if I borrow Bowl inherited from I book it have both I library items and I book items but then you're calling it an I borrow Bowl but that would seem to apply to audio books and DVDs as well the problem is but you also have as I book stuff which again gets back to we're implementing things that we don't really need so I don't think that works to connect the two and so what I would do is I'd actually create a new interface I would call this interface I borrow Bowl book which we inherit from I borrow ball oops and I book and there you go you don't have to add anything more to it it's actually kind of empty interface but what it does is it joins these two so now we have the interface called I borrow up a book and if I go write a book class instead of I library item I say I borrow a book nothing else has to change the book now implements everything we have in both the I borrow ball and I book and I library to them and technically also I borrow a book which is just the combination of two so see how I'm kind of I'm kind of pulling it apart instead of having one big gigantic brick I now have little pieces that I can put together in different ways as they make sense so now for reference books I can say instead I library and I can say I book because I book has just a stop that applies to a book but I don't have to implement and a check out information associated with borrowing so now I have just what applies a reference book the library ID the title the author and the pages which is all applies to a book but it's not a borrow book the actual book class is a borrow borrow bubble book how it's hard to say so that allows us to use our interfaces connected together or disconnected if it makes more sense one way or the other now let's look at the other atoms here we have audiobooks well as an audio book a book No but it is vulnerable we also have this extra run time in minutes so let's create a new class our new interface sorry where I call this the we have two options here we can go right away for the simple one or we can go to the little more a couple extra steps but more flexible in the future I want to go for the more flexible in the future I'm gonna say I audiobook an audiobook implements from I'm sorry inherits from I library I'm actually implements so what does a audiobook have well it has a runtime in minutes that's specific to an audiobook and let's check it anything else out it does not have pages let's get rid of that we do have a borrow information we'll go ahead and change this to an I borrow bubble in a minute but I think that's it for I audiobook but notice I didn't inherit from also from I borrow bubble and the reason why is because there may be audiobooks that we cannot borrow so therefore now create a new interface called I borrow Bowl audiobook and this again will just be a combination of I aw do book and I borrow ball and I audiobook also pulls from a library item so now we can take this interface go back to our audio book instead of I library item it's actually I borrow Bowl audio book everything still applies the interface covers all of our different data points here and it makes sense okay we've combined things in a way that allows us to have that open closed principle remember that we're not come in here and modify audio books down the road that way it since we thought it through if down the road we say oops we have a reference audio book has to say the library we can't check it out but it is part of our inventory no problem instead of implementing this interface will implement just the I audio book interface doesn't have any to borrow information it just has the stuff about an audio book and again that's that sets us up for success down the road let's create another interface they're gonna clean us up in a minute so don't worry that we're kind of you know making huge big chunks of files right create an eye let's create iMovie class now here is one of those times when I could think far down the road and say II may want to change us and maybe I don't and so right now I'm thinking if I do or if I don't I could do an ID VD class and I think I probably will but here's deal if I say iMovie it's not the end of the world because weather on DVD blu-ray or VHS that's almost dead hopefully is dead but all these other types it's still a movie but I'd have to have some way of indication indicating what type of medium it is because if you don't have a blu-ray player you can't there's no point in borrowing a blu-ray and so that's where like an enum would come in but then we're always changing the inu on the road to say oh we added a new type of you know disc whatever it is maybe it's a digital movie instead so that's again violating the open-closed principle where we're modifying that EMU all the time so it prime makes more sense to do an i DVD class that way we can add another class called a blu-ray or i digital so what's mine is public and that's next let's go ahead and find out let's find out what a DVD hat is different what different about a DVD so let's start with has no author or pages so let's get rid of those it does have a list of actors it also has this run time in minutes now those of you who have sharp eyes have noticed I have seemingly violated the SRP principle I'm sorry the DRI principle don't repeat yourself and how have I violated that well I have a int runtime it's full in the iDVD class and I have int runtime minutes in my audio book interface so why wouldn't I join those two or somehow some kind of inheritance going on or implementation and the reason I wouldn't is because an audio book and DVD have nothing in common technically yes they both have run times they're two different things it's it's really trying to compare apples and oranges by saying they both have an outer skin yeah they do that doesn't mean that anything alike so just be careful that you don't just look at a property name and say oh that means it's a relationship between audio books and DVDs there's not so this is not violate dry now you may find a way to create an interface that would be like items that have run time and put the in trun time in it and then inherit like iDVD inherits from items that have run time or implements that yeah you can do that unless it really makes sense it's probably better to just separate those two out and have a copy with again they're two different things so I just you know one of those words of wisdom don't just get caught up in they look the same therefore they're the same okay so we have iDVD which has a list of actors and runtime mints so with these two things being created we could just again have it come from the I borrow bowl but we're not going to we're going to come from the AI library item and that'll create a new interface called I borrow Bowl d.v.d let me get public comes from iDVD and I borrow Bowl now I can take this interface we can apply it to the ID or the DVD class everything checks out or it should let's find out why it doesn't now we don't want to we don't want to rename I library Adam is saying we do have to implement the interface let's find out why because it looks like we should have entered ah I see why instead of oops instead of copying let's say I cut so in here I have these two properties they should be on the DVD they're not at they in public there we go and now we correctly implement the I borrow bowl DVD ok so one of the questions that may come up in your mind is this interface here looks squirrely we don't have any types of properties or methods in here it just is a combination of two different interfaces so why is it we couldn't put those two interfaces directly on DVD which is a great question and the reason why is we could first of all that would work and it would seemingly function no differently but if we have this I borrow ball DVD interface we can reference this and have access to all these properties and methods it without having to any kind of casting issue so we can just say you know and let's actually go do this let's come over here we'll add a reference to our project our demo library and if I come over here and I say that I have a I borrow Bowl DVD I'm gonna call it just DVD equals new DVD ok so I'm using the interface as the the variable type not the actual implementation so the interface will limit you to only what is in the contract that interface so let's look at what DVD has access to actors borrow date borrower check in check out check out duration days hour get due dates I'll get type well we always have that library item run time as title so it has access to everything we need in one interface now if I change this instead of this instead of this one interface I came over here and change it to these two it still works but over here I'd have to say may I borrow ball which that'll work but now let's look at my list I have borrow date and borrow cool check-in/check-out great checkout duration in days get due dates and that's it so where is my run time it's where's my title where's all that information well that's not in the interface I have to come over and give me an eye DVD which now we have our actors we have our library ID runtime and that's entitle but where's all of borrowing information well I don't have it so the only way to get all that information is then cast it to the actual implementation type which is a type DVD not really what we want to do so instead by creating that that combination interface I can come over here and I use the I borrow bowl DVD and now I have access to everything that I want this will come into play a little more when we are working on the next part of solid the D and we start using interfaces to bring in information instead of having a direct dependency on newing up a specific type and so we'll get into that more but this right here is a variable valuable concept because we can combine those two and then have access to both interface worth of information into one kind of super interface which originally we had one super interface with our I library item but that wasn't good because that interface then didn't work with all of our different types so and say it broke it apart in a little pieces but then combined those pieces up into larger interfaces that worked for a specific area but then we're modular enough to take pieces out and use it for a different area so we're using some of the same interfaces for the iBook or I'm sorry the book and the DVD and the audio book these are all borrow ball and so they're all coming from that one bar Obul interface so that that modular Ness of the interface instead of having a one monolithic one allows to be more flexible it allows us to not violate the open-closed principle it allows us to again still be dry that don't repeat yourself and it allows it to more future-proof now as you can see this does make for quite a few more files which sometimes people get a little freaked out about the idea of having lots of files me not so much and the reason why is because folders are free so Cree has many folders if you want to make things work the way that you understand them best so for example I think what I would probably do this is kind of a rough cut it and I might might change it as we go but I might create a a book folder and then move the book maybe in the reference book they're really similar but they're not the same then then the interface for I borrow Bowl and also the iBook and then I create another folder and again this is a rough cut you might want to change it if you want but I create audio book that dragon audio book I audio book and I borrow Bowl i body audio book then create another one in this case I might create a movie folder because you might want to put blue right in here as well but let's just create DVD make it clear for now again you can change down the road so I borrow ball DVD and I DVD now I'm still laughed with a couple of interfaces that don't really apply to any of these three folders so I could do is I create another folder or I could leave them at the root I think I probably do is create general interface folder and then just drag these into it so now your project looks a whole lot cleaner if you want to do anything a book well there you go now you could say again folders are free so if you want to you click under book right click and say maybe interfaces and drag the interfaces in here and then have another four implementations or lead those at the root of book I'm not as big a fan of that because it separates out it separates out the the interface and the implementation I kind of like to keep them together so book and iBook and I borrow ball and the reference book but it's up to you again it's how you decide to organize this isn't really that important now the again the one thing to remember is if you now create something in this folder it will no longer have the name space of just demo library it will be demo library dot look which could cause some issues of not having using statement or me making sure you have to have one of those in all the different places just know you can take that namespace and change it to ever you want and it won't hurt anything it might just mean adding a namespace if it's not already there so that's just what I think through is your organization process I might actually have these folders one level deeper if this is a truly a a library a book library application because I might have something for reference materials or you know consumables or whatever might call it the things that we actually lend out of library because there's so much more to the application than just lending there's the collection of fees and there's the user information and there's the inventory management and all that other stuff that goes on besides just the items in the the inventory so that's it that's all there is to the interface segregation principle it's the idea that we don't have one monolithic interface that doesn't reapply to everything that implements it instead what we do is we break that interface into pieces there can then put together again in a more modular way think of it like your car if your car was just one piece whenever it broke the whole car breaks but if it's just the door handle it breaks you can take the door handle out and replace with a new one that's more we're talking about with this modular approach to interfaces the idea that it's not just one large thing that if we have to be a change it affects everybody but instead it's this module thing we can put together in different ways so that Eilen something new comes along it's just taking our current existing chunks putting together a new way and there you go for example if I was going to add a new class lesson here I should cry new folder for it you know what digital movie why not so let's create a class we'll call it a digital movie class and to start with let's look at DVD class itself I'm gonna grab all this stuff and I paste it in here because that want to have to implement the interface a whole bunch of different ways but really I could do that now it's a digital movie I don't necessarily want to do that I might want to create an interface for the eye digital movie and then create the I borrow bowl digital movie but really since it's digital there's not a whole lot changes so may I do that which does bait the case maybe should have called this movie instead of DVD but you see the power here of I'm done I create a new class it's for digital movies and the interface is good to go we're all set here I'm set or I could follow the same pattern and create my own interfaces and use I use the I library item and use the I borrow Bowl but then create my own you know list of string actors and runtime minutes because maybe I want something else there as well so there's options here I can do and you're not gonna get perfect the first time now according to again the open closed principle you don't change those things which are already in place that's true but that's the difference between a application in production versus an application in development the open closed principle doesn't apply in the same way for a project in development you can modify all the different classes you want but what you're trying to do is set them up then so when you go to production they don't have to then change again so you could you could tweak this modify as as you're building yeah just not right what it comes down to is the better you plan the better your application is set up for success and so keeping these solid principles in mind when you plan out your application plan out your interface design and say I know we're to have DVDs and blu-rays and maybe some stuff like digital movies from the future but we want to call mall movies and just have three different implementations one for digital movie one for DVD one for blu-ray that's how I tell apart instead of an e new you can do that you can also say note we want to have an interface for each of the different types because who knows if digital movies have something different about them then blu-rays do so that's all to you the more you do in the design process the less you change in development which makes your life a whole lot easier and then the better you design and develop your application the less you're going to violate OCP the open-closed principle and also the the ISP so that's it for the ISP or the interface segregation principle it's just breaking those down into little pieces if you have any questions post them down below and I will try and get back to you an answer as soon as possible also don't forget that this source code will be on my blog there's a link down the description below that will send you right to my blog and if you like it I appreciate it if you'd let me know by hitting that like button as well as let me know in the comments all right thank you very much for watching as always I am Tim quarry
Info
Channel: IAmTimCorey
Views: 75,840
Rating: 4.9764113 out of 5
Keywords: .net, c#, c# training, c# tutorial, code, design patterns, design patterns c#, practical design patterns, programming, s.o.l.i.d, s.o.l.i.d design, s.o.l.i.d principles, s.o.l.i.d principles c#, s.o.l.i.d. design principles, solid, tim corey, training, tutorial, visual studio, interface segregation principle, interface segregation principle c#, interface segregation principle c# example, interface segregation principle uncle bob
Id: y1JiMGP51NE
Channel Id: undefined
Length: 40min 24sec (2424 seconds)
Published: Mon Apr 16 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.