SOLID Design Patterns

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi welcome to visual studio toolbox I'm your host Robert green and joining me today is filter pixie hey Phil hey Robert how are you good welcome back to the show thanks thanks for having me again Phil is an MVP a trainer I don't figure conferences and author and a consultant and a guitar until the swing code great so we were at a show recently we've been a couple times recently actually we were sitting around talking about what types of things that we should be telling people how to do you know we spent a lot of time on all the new stuff you know bought frameworks and you know and then stuff like Asher and DevOps and you know xamarin there's a whole bunch of stuff going on but one of the things that we sometimes kind of gloss over is kind of the standards right the how to become how would you no matter what you're doing be a better developer and so you suggested that we should spend more time doing that kind of stuff yeah because you know one of the things that people want to do is greenfield projects right file a new project build something from scratch latest technology play with all the toys reality is most of us are janitors we spend our time cleaning up either our own code or somebody else's code and you know I was adding features bug fixes or whatever you know the average life cycle of a project is really about 10 years right right so so how do you make that life less miserable right and one of the ways is really focusing on the quality of your code okay I mean you can obviously upgrade to the latest version of the tool because Visual Studio has new tools and whatnot but this is more about the code you're writing not the IDE yeah so just because there's there's new search capabilities in Visual Studio it's not going to fix bad goat right and what I mean by bad code is is every code you write you look back even if you wrote it yesterday you go I could have done that better right so what we want to talk about we've come up for a long time is solid right it was a solid principle single responsibility open closed and we're going to go through those okay but it's just some some foundational principles that if you think about these as you're writing code and the other thing is someone up I like to look at it this way pretend the next person looking at your code is an axe wielding psychopath right and if you write bad code if they have to maintain they're going to get a little cranky with you now in reality who's looking at your code next it's probably you right right six months down the road you pull some code down you have to work on it you're looking at this code going oh this is terrible who wrote this you look at the commit log and you realize you wrote it right and you're like no no it's fine I love this code let me clean it up right okay so what I want to do is go over a few guiding principle and I try and follow and this is again this is whether you are starting a new project or you know neck-deep in an existing project that you're going to be on so write several years yeah and you know we've talked about that also with the Boy Scout principle get to that you know there are certain things that you can do to clean up technical debt okay and we'll talk about it's a balancing act define technical debt so so technical debt is code smells right code that could have been written better but wasn't necessarily not all technical debt is bad okay these always have to pay it back I mean if something works it's in production I've got code written in BB six that's still in production and people are still finding it useful and I look back at that code every now and then and go ooh I don't my name attached to it can I please rewrite it right but it works right and they're not having performance there is a conflict rewriting there is a cost of rewriting so you have to really to decide is it worth paying that debt back and and it's a balancing act okay right we all want to go back and fix it but it's not always the best thing for the customer right right so when we talk about solid Robert Martin uncle Bob Wright wrote this paper principles of object-oriented design was the official title and everybody just refers to them as the solid principles okay and and it's single responsibility open closes Cubs substitution interface segregation dependency inversion right so I want to just a few slides I know we're gonna get the code okay but you know but a picture's worth a thousand words yeah and I'm sure you probably had a knife something like that when you're in Boy Scouts right I had one of those and you could do anything you wanted to except cut anything because you could never get the little knife all right right and the problem that we run into as developers as I call it the kitchen sink mentality right we've got a class out there called something utilities and we just start dumping stuff in there right or we've got a method if I just add five lines into here then you know I don't have to create all a new method or a new class right and when we talk about single responsibility you really want to have your methods your classes focus on one job and do it well it's like driving can you text and drive in Washington State I think that's illegal right it's illegal it also gets you in trouble yes right so if you're texting and driving you aren't going to do one of them very well right right and hopefully it's the texting you're not doing well you don't cause an accident yeah same thing with code if you're trying to do 40 different things or even two different things in a method you're not going to do them optimally and plus if you go to change the one thing you don't know what kind of side effects you're going to get from the other right so you got this confusion so just have one thing being done in each method you have lots of really small methods and then you're going to have lots of really small classes okay and people will say things like well then that's a lot of files and I say so what all right with Visual Studio these days you can find anything right all the refactoring tools yeah so the next one is the open closed principle what we want to do is we want to extend our classes instead of modify them and what I like is the picture of the house right if you're going to put in an extra bedroom a patio room a deck that's pretty easy to do right if you want to put a new basement on your house that's significant and you run the risk of break-in your entire house right well if you've got code it's in production it's working people are using it why would you go change that right so we want to make sure that we extend code instead of just changing things at the base level because again we we risk those side effects there's unintended consequences it realize the cold beer or at least some sort of cold beverage yeah and what I like about about this slide and we really want derived classes to be able to stand in front you ever call and what I mean by that is programmed to an interface so if I have an irepository that I'm programming to I can plug program in or instantiate anything that holds that interface it's like a beer tap if you go into a bar and they want to switch over from a winter shanty to a spring I don't know something I'm not a beer expert they don't have to rip out two taps the lines so no infrastructure no they just flush the line put a new 1/2 Berlin and they're pouring the new beer ok think of and this happened to me in in the late 2000s we were writing an application it was an e-commerce site we had a certain credit card provider we were using CFO calls and says we have to switch and this is like six weeks before release and he said ok why do we have to switch credit card providers he said well we just have to write you have to use this other one well it turns out he was playing golf with the sales rep for the new one lost around the Gulf when we had to switch if we had programmed everything to be directly tied into that additional credit card provider we would have had to rip out a whole bunch of code that already been tested has already been through user reviews and QA and everything else instead we actually had an interface that we could program to we swapped out the old one put in the new one had to tweak it some but basically we're up and running in about a day can write the next one is interface segregation you probably don't know what that is that is the control panel on the USS Missouri the mighty moe fortunate enough to go to Pearl Harbor one time and they had imagine a room about the size of the studio covered in dials to shoot the big guns they had an entire room full of people mainly turning knobs and these guys knew how to do it they could hit a target 100 yards in diameter right right miles and miles away when they went to bringing out a retirement for the first Gulf War depending on went huh nobody knows how to shoot the guns they had to bring a whole bunch of servicemen out of retirement to teach the new guys how to fire the guns or that interface is way too complicated okay right so anytime you have a complicated interface intellisense is great right but if you hit dot and visual studio and there's a scroll bar in the intellisense window your developer is going to be stuck in analysis paralysis and go I don't know which one to use a lot of times are very similar right so we want to make very fine-grained interfaces specific to the job at hand even if that means making your own interface to wrap up an existing framework class you want it to be as quick as possible for your devs to be productive okay the last one is dependency inversion I think it's the most important and probably equal a single responsibility did you drive to get here today yes I did did you build the engine before you could drive here no I did not the engine was already there right yeah yeah so think of software how often do people build the engine before they drive the car if you're newing something up in your method and then using it you're building an engine every time you want to drive the car you were locked into that specific instance and you can't use anything else what we want to do instead is subscribe to the AI car interface you have more than one car you can drive either you've had rental cars before as long as you subscribe to the AI car interface you can drive it right which is you use during wheel and accelerator Indy accelerator some states they have turn signals not all states use them evidently but you want to get in software so we're going to inject those things and like the engine like the data access layer like the Republic we go to that point you're left to explain why like I understand everyone's understood the principle but ok you know sometimes you know explaining why you need to do that I'm you know I want I want to be to be able to plug different things in but in my app I'm only using one of them in the first place why do I need to pendency well you're not always using one of them your visa log4net yeah okay so long term that's a logging framework based on settings in the web configure the app config you can change the logging level and you can have it be very verbose or very very light right right and what we're doing is we're setting those properties in the config file which is then being set at runtime not really the dependency injection but that is an instance where we're changing the functionality of something without having to change code so let's say that I'm using a credit card provider for my e-commerce site and I say foo equals new credit card provider and food dot check credit card food check address food charge credit card okay so now I have to switch credit card providers and now I have bar and say bar equals new credit card provider yeah and it's not barred check address it's barred address verification so now I have to change all that code writing ken whereas if I just had injected in an i credit card provider and we'll talk about it with some of the patterns so we could put an adapter around that so that subscribe to a common interface then I can change out the credit card once I've given then creating a service class that has a fixed set of methods and then your service class just calls a check address or verify address or whatever so that your front-end never has to change okay so how are you getting that service class into the method to your calling you dim it up okay here are VV guys he said to do it up dim it up you knew it up here once they both work I know I do that too so so that's true but what if that service cost has to change what if I'm going against a but the service class and maybe we're going down a tangent here but the service class has a method called check address okay and it's always going to be check address don't care what the thing I'm calling calls it check address verify address address verified doesn't matter but you would have to change the code in the service class yep but the thing that calls the service class always calls check address passes in something and gets back okay sure no so I'll be coding to an abstraction okay and so you solve the problem in one part of your code and you kicked the can down the road to another code all right so now you need to change something in that service class yes right do you want to change the code you always want to pass in new object here's a better example that might make more but then echo taking it down the road to the inner let me let me let me let me say this so EF core now has an in-memory provider mm-hmm right and it's great for unit testing so I'm using sequel server my real app I don't want to write unit tests or actually touching the database because that's really an integration test and that's a different type of test so I can inject into my AP net core application a context that's using the in-memory database as opposed to a sequel server and not change any of my code okay so I'm just injecting in a different database provider because it all holds the same thing we are that's what's with you and I having fun here with the viewers in that turn but you know what that's what post-production for so this could be a really short segment if you need it to I'd add it and it will probably just leave it so let's move on let's move on so everything is dry right it's not one of Uncle Bob solid principles but it's don't repeat yourself anytime you have repeated code you run the risk of introducing side-effect bugs okay all right so I've always said if you write something once think about making it a function you write something twice please please please make it a function you write something three times you might want to stop being a developer okay because if I've got it use all time of case statement I've got a case statement over here I'm going to clipboard inherit it over here which is an anti-pattern right yep clipboard and I change it over here because I'm working in this code and I totally forgot I wrote it over here so now I can make five different types of pizzas if I'm this part of the codes only four types of pointers of them in this cut and part of the code right so we really don't want to repeat ourselves the Boy Scout principle is what we're talking about what we got to legacy code so I've got two humongous app I've inherited there things in it there's you know five thousand line methods called execute with 36 parameters and if you want to eliminate all that technical debt you're going to spend who knows how much time just rewriting code right and there's not there's some value in that but not really value to get get translated to return on investment so what you want to do is if you have to go into that code leave it just a little cleaner than you found it okay so add some unit tests right maybe extract some left it's really easy in Visual Studio to pull out a method right and then write some more unit tests don't fix it all at once just chip away at that Tet seconds you've got a mortgage you know you pay an extra payment a year you cut the life of your mortgage down by five years typically right right so just you know in the Boy Scouts always leave something cleaner than he finds it right right hence the Boy Scout principle yeah last is separation of concerns right so I'm a Star Trek fan bones would always say you know dammit Jim I'm a doctor I'm not an engineer or weapons specialist fill in the blanks right here's what we want to make sure that our code is doing what it's supposed to and nothing else and this is very similar to single responsibility but it's kind of more of a macro vision of it we talked about separation of concerns let's have a data access layer that's isolated so that if we don't want to use in a hibernate and we want to switch any of you framework all this code doesn't change right we're passing in we're injecting in an irepository that now calls an hibernate or in any framework right and if you've got UI concerns MVC is a great example of that right we really have a good separation concerns than that okay last thing I want to show is just a quote Phil hack had this on an all net news group that used to subscribe to years ago but it's such a great quote and it's so powerful when we talk about design pattern so we've moved away from solid let's talk about actually you know how you code in a solid manner and design patterns really help us to do that the problem that I see so often and why I came up with this talk initially is people treat design patterns like Dogma like this is the only way you do it right I have a hammer now everything is a nail and the best part of this quote and your viewers can read it but I love the fact that you says the goal is not to bend developers to the will of some specific pattern but to get them to think about their work and what they are doing if you just look at the second part of his statement to get them to think about their work in what they are doing that's what we really want people to do is stop and think write program is not a typing exercise it's a thinking exercise okay right so how can we apply critical thought how can we learn from others and write cleaner code okay all right so let's dive into some code and talk about some silly not all of them we would be here for days if we wanted to talk about every pattern there was this codes all available and github will be in the show notes yes and I have unit tests around them and the reason I do that for a couple reasons I'm pretty fanatical about testing code but the other reason is if people want to download the code and play with it and tinker with it if they break the unit test they broke the pattern okay all right so you're building a website and you're going to use any framework and firing up a context is the most expensive part the context it creates a connection it checks a database make sure everything is in order so it's kind of an expensive operation and for most people not that bad right but but it's something that you want to do on every single database call so that's something where you might want to create a singleton and the singleton by definition means there will only ever be one of these things in existence per ab domain okay and for most of us we just deal with ab domains I mean if you're doing some multi-threaded stuff it gets a little more hairy but the way you implement a singleton the way you recognize the singleton is here I've got two different variables they're both set to the singleton instance and we'll talk about that shortly and I'm just running a test I say assert that they are the same now our same and unit testing means that they are pointing to the exact same item on the heat okay right change a value on one of them and I make sure that they're equal on both so that's the symptoms that's the result of having a singleton let's look at how we build this and I guess it's a very simple pattern we create a private static instance of the class we're building and you'll see in all my demos the names are terrible and really bad at naming things but the three hardest things in software development are naming conventions and off-by-one errors we also have this sync log object now I will say there are several different ways to implement singleton this with just one write a dead giveaway is a static property called instance that's just a convention not required for the pattern and then what I'm doing is I'm checking if the instance is private static incident variable is not null then I've already created one and I can just return it to the calling code if it's not already been created I put a lock okay so this makes my code single-threaded open up remember I know you're familiar with locks if some of your viewers not remember log see and then we do another check to see if it's null the reason we do this is we've got multiple threads coming in potentially get gated by the lock one gets through followed by another one so another single file in line if this one creates a new instance and we're not checking again to see if it exists this one could create a new instance as well okay so we just throw in our lock and then we simply make the instance a new version and a new instance of the class and we're off to the races and that's all there is okay so this helps with cutting down and repeated code and and making sure that if you have to have state across different calls this will do it for you so like I said a very simple pattern so they can't want to talk about and I use this a lot is a simple Factory and a simple Factory is usually used to instantiate different options so for example let's say we're creating a pizza factory and I have to give a shout out to head first design patterns it's a book it's very very good book and we'll put it in the show notes as well some of their examples I leveraged okay for this talk and one of them is a pizza store so let's say we want to make a different spot type of pizza we could put an if/then or a case statement everywhere we're recruiting a new pizza in code but then we be repeating ourselves so we can encapsulate that in a simple factory and it's called a simple factory because it really is very very simple a lot of times they'll be just a case statement okay right and we call into this now in real code I wouldn't just statically create these things I'd be calling a new database or whatever I'm doing right but let's say for example that I run an e-commerce site and we're going to try and get different shipping methods right if you're going to Amazon and you buy a book they're going to pack it in a box if you buy a steak they're going to pack it in dry ice you buy something fragile they're going to pack it completely different okay right so I can get a new instance of that packing class just by using a simple factory now according to the Gang of Four it's not an official pattern so I just have to call that out me and more pragmatic than academic so it doesn't matter to me that it's not an official pattern we're going to jump ahead to combining the factory method in the abstract Factory wait go back oh yes sort make sure everybody understands why are you creating the factory what's the difference between those methods well yes shortly so here in the simple factory all I want is one place where I can create things okay so it's more like your service class right you were creating the we were talking about earlier with dependency injection if we're creating something we want to have one place to create it so it's a single responsibility the factory job is just to create things it doesn't use them it doesn't do anything other than say hey I need one of these and throws it back to the code okay so the I pizza is a pizza so every pizza is similar and every every pizza yes then they're represented by an i' pizza' mm-hmm which looks like what Oh certainly yep sorry and then we're a little bit of a time frame so I was not hitting that button we're in a little bit of a time frame and so I just want to say here is an ID pizza okay got some toppings it's got a doe type seasoning sauce type and then I've got some methods that exposed all right dad and those methods will come into play well although there are depending on the type of pizza you want you go through a different path which you always return an instance of I pizzas yes and that's why you created a factory like that drop dead of having four different classes potentially for the different pizzas or four different methods and different places yeah and this is just the UM the Scott substitution principle right I want to be able to program to an AI Pizza Pizza is going to have toppings it's going to have a dough type it's gonna you have to cook it cut it those types of things right if I had to cheese pizza and a pepperoni pizza class well that's easy but but now let's say you got thirty six different toppings right let's say you work at Starbucks right and it's not pizza but think of all the different combinations and variations right Oh coffee you can order right yours I came right down to it it's all the same thing it's liquid in a cup yeah absolutely okay all right thank you for delicious liquid in a cup of absolutely hot ya know play the awesomeness of you I've got my Starbucks up I'm my band all right so let's there's two other factory patterns that I combined into one and it's the abstract factory and the factory method okay and it's easier just to explain holistically how it all works together than to go into the minor details between it so let's say we have this different types of pizza stores mm-hmm we've got a new york pizza store and we want to order a localized pizza now New York style pizzas very different in Chicago yes right and we want the pepperoni and then we're just going to assert that it's a thin dough the red sauce and it's spicy let's say we have a Chicago pizza store if it got greasy be nice I am being nice it's good so Chicago pizza store and we want a sausage and it's going to be deep-dish and tomato basil and mild season yes right which can all be changed but this is just a default now here's the important thing let's think about I have a pizza franchise right right mundo right pthrough no and I want to want to franchise or have people franchise my store yeah we want to control certain things for example the order of execution so we want them to make the pizza cook the pizza cut the pizza well actually there you go I just messed up the order put it in a box yeah then cut it right and then deliver it right if you get that order wrong bad things can happen right you can put all the dough and all the toppings in a box and put it in the oven and light your store on fire right so there are certain things we want to control but certain things we want to give them flexibility - yeah and this is also Chicago pizzas typically not cut first you just put them in the box it depends right so the franchise by me cuts it okay so not first but they put it in anyway we're getting totally squirrel here so let's a little bringing up pizza what do you want oli not all that but that's why I talk about things that people can relate to right so I used to give demos on more business II type things yeah and so like if I was talking about banking here or expense reports somebody say well that's not how expense reports work and we get totally lost in the domain as opposed to just looking at the code so we've got a pizza store if we look at the pizza store based class itself it's got an ingredient factory and the base ingredients just you know it's very simple we'll talk about those but here's what I want to talk about the order localized pizza so so this combines a factory pattern with the command pattern which we're going to get to a little later where we say create your localized pizza I don't care what type it is right so the inherited store will make a Mormon New York style west coast you know California pizzas style or Chicago and then we want to control the order okay and then we're going to return it now where this really comes into play let me go back to that whole ecommerce site right you order something and you put your money in and then a couple of days later it shows up on your door right so if you order a book they're going to first of all make sure that it's in stock pack it well pick it pack it ship it right right same thing with no matter what you order those exact commands happen but how those commands get executed very very different based on what you're ordering okay so we want to control the order but not necessarily the exact functionality but we also want to make sure that the store the base store doesn't care whether you bake it at 350 degrees for 30 minutes right or at 400 degrees for 12 minutes it just says bake okay all right there's a lot more we could talk about that but let's get to some other pattern okay let's talk about the adapter we're now moving into structural pattern so we were done with creation was three main types of prior to said that structural behavioral and creational okay so this is structural so the adapter pattern is also hugely helpful so if you're old you're old enough to remember two prong outlets in your house I don't think they build them anymore but invariably my dad would come home with something they had a third prong and I have a two prong outlet yeah so we did what everybody died broke off the third prong and plugged it in right well we were supposed to fit into it read it to plug it into an adapter takes a little wire to grab attach it to it yeah in software we do the same thing with an adapter we make something appear to be something else to make it easier to code okay right let's go back to that whole ecommerce thing when they're switching out we just wanted to check a credit card to fievel's valid and then we want to charge it and we want to check the address or we didn't necessarily care how all that happens we just want to be able to call that and not fight two different names right so let's say we've got three types of cartoon characters we've got a moose yeah and we've got a flying squirrel moose and squirrel and we've got a bad guy okay okay now the problem with the bad guys and the squirrels and the nice loose loose nieces nieces we'll call it nieces so a bad guy can only do two things you're driving it can shoot right if we look at the flying squirrel it cannot do two things fly and drop acorns and if we look at a moose it can run and it can charge okay right but now we want to operate magic tricks they can do magic tricks - I should add that in let's not party interface so there'll be an extension hmm and it goes the modification so if we look at these we can certainly work on them in the left so if we've got one squirrel one moose and two bad guys we can put them in a ray lift which is not strongly typed and then if we want to act on them we would say okay if object is of type then call this method but then every time we want to act on those we have to remember to translate those methods into something that makes more sense holistically so what we want to do is we want to make them all look like in I character okay and I character has three methods chase fleeing attack so we want to map those so the way we do that is by making adapters now I will say from a doing responsibility standpoint I've broken things here because I have multiple interfaces and multiple classes in one file right really not a good idea for support ability maintainability it's demo code it makes it quicker to get from one - and not okay so I do want to point that out so the way we turn a moose into an AI character is we have this moose adapter class so we inject in and I move my roars coding to an interface so we don't care which moose it is right it could be something it derives from I'm I could be a baby miss it could be Bullwinkle it could be Bullwinkle wife okay so so right here yes in this application you have a moose mm-hmm so you could pass in moose I could now the benefits of passing in a moose is that you are pre you're getting ready for if in the future you would ever have different types of visas or mooses nieces or misses the front the plural of mice I don't know mooses right window bullet so in this instance right here at that's just a it's not 100% necessary in immediately right because it's instead of dealing with a moose you're dealing with a motion and I moose it it can seem like you're overcomplicating given that there is a moose that correct well so so what we are what would you say to somebody who says that to you so because I text to work what am i gaining well it's not a whole lot of extra work and really just saying I moose instead of move I am there is the Agni right you ain't going to need it right so there are times when you want to just back off a little bit okay of what I have found with things like programming to an interface is it never hurts okay and quite often comes in handy okay so there are things that I would consider overkill like using an IOC container inversion of control container which when your viewers download the code I use unity not the game engine but the IOC container that Microsoft wrote to do some of this in the longer version of this talk right right I don't know the classic example is mvvm where even though the standard is that you name your view model after the page and then in the page you instantiate a version of the view model alright you don't do that use a view model locator right which you know you're in the customer page you're going to call the customer in the model that's the convention right and then there it is under view model customer view model why you know so you you might have said why am I going through adding all this complexity of a view model located which I now have to learn how to use it's not a problem getting one there's there's plenty out but not going to learn how to use it when I'm in the mousse page and I'm going to call the mousse view model let's move on right so so there's a couple things to that and I totally agree that a lot of times using those locators is overkill if you're moving the dotnet for how somebody would argue could I get it this is okay are you okay right and in this particular code example I couldn't really refute that right I could easily change this to that right and it wouldn't break the code it'll work just as well right so the question is what's to be gained by switching into the habit of calling the interface in these simple types of things if you get in the habit of always coding to an interface then when you have to start paying back that technical debt then you can start injecting different things you can use mocks to unit tests right so I can write a unit test about this about this entire adapter and not have a mousse class right I can create a mock representation of an eye mousse put it in here and make sure that this code works and I actually have unit time with mocks in here to show how to do that so that's interesting so in an application we're calling data it would make it a heck of a lot easier to use fake data while your developer would yeah because you're bringing in an eye mousse and your real mousse which calls the Moose Factory which then goes out to the database and bring stuff in or you're passing in the mock mousse which is a hard coded data sample data so that you can yep and my unit test has to make sure that if I call chase it's really calling the run method on the Moose okay on the eye mousse right right and not actually executing it what if the run method was charged credit card right and I had to pass in a real credit card number and it would charge it right right but I could bring in a fake credit card processor and just a Earth's that that method was actually called through the Mach framework right okay cool but from a strict coding standpoint in this example you could argue that you don't have to code to an interface but right if you do get in a habit of coding to interface it's very little overhead if any and I don't have to talk quite a bit and I think they they sometimes tend to just focus on the mechanics of what you're doing without stopping to remember that you do it this way there are potential benefits right which you may or may not realize in this particular example but if you understand now oh I see this will make it easier in the future for me to do something like this and it's you know it's one more letter I Mach versus or I moose versus moose it's worth setting yourself up for being able to write advantage of it if you then understand what the benefit is down the road right absolutely and actually there's several been several books have been put out by some of the software luminaries and say you shouldn't use the I moose name you just call it moose because everything should be the interface and it should just be assumed that everything you're talking to is interface we're not there yet as an industry speaking of mocking and testing yes look at that house right up so I have my I moose and I'm creating a mock which is just a proxy around the I moose and I'm saying the behavior strict and this is I'm using the free version of just mock for this and what behaviorist Rick says that if I'm calling something that doesn't exist yeah like if there's a method that I try and call it is controlling exception yeah so I arranged that what I call charge it actually is going to return 10 and it must be called but it says if anywhere in this test charge is called return 10 and I'm saying it has to be called right so this is annexes expectation so I can go then assert that these things were called appropriately okay so I'm testing my adapter without having to have a real moose right all right so I have the different adapters here flying squirrels maps it to one thing to another and and and the other reason I like adapters is not just we don't normally program around Bullwinkle and rocky and Natasha and Boris but a lot of times we have legacy code we have to call into or we have something in the framework that's difficult to use or we're using a third-party app that is confusing but it's mission-critical I can write an adapter around that to simplify it so if you're in I'm going to show actually you know what let's just go onto the facade because the facade is very similar to an adapter but the difference between the facade and the adapter essentially is an adapter as I'm taking one thing and shaping it to look like something else and if I saw it I can take many different things and make it look like one thing okay right so let's say that I've got this class that implements I confusing and I overdone so I overdone again just made-up names but we've got this business-critical assembly that we have to call into okay and we've got these wonderfully meaningful names do something do something else and do something again with x y&z and oops I ran out of letters I have to start over a day okay right not very maintainable code this would be significant technical debt in my mind and we've got to zone of one that's like confusing and it's it's a great feature so we've got execute always a great name for a method less than one method - this is somebody learning how to use Visual Studio to add a new method and then another method to is an overload okay well I'm calling into this all the time right I have to because that's the way my workflow goes okay but now what I have to do is if I want to remember which one of these methods I should call I either have a bunch of post-its on my desk yeah or I have to use reflection or reflector or some tool they will look at the source to see what it is so what we want to do is we want to build a facade so somebody has to bite the bullet and take the time to learn which of these methods we need and call them something better right and wire them up so we really need these two methods and our overload so add three numbers adds and multiply with some different items okay so when we build this class we're just going to call into the methods on the bad classes okay right so that as I'm coding and I need to add three numbers I just say foo equals new better API food add three numbers this has just a middleman yes ACLU's cleans it up makes ant-like nicer easier to use okay right all right decorator is absolutely awesome I wish I would have known this a long long time ago I wrote an application it's still in production and it's a configurator for high-end bicycles and it's all written in JavaScript long before we had all these great JavaScript frameworks was plain old Jas and it's easily I don't want to say it out loud five thousand lines of JavaScript if you pick this frame then I go through and say well these are its hires tire rims are available these are the brakes are available and just imagine the treat configuring a bicycle from the ground up and it's I I actually volunteered to rewrite it for the guy for free just to get my name off of it right because it's in JavaScript so anybody can look at the source there's so much better way to do it and this design pattern is phenomenal it's called a decorator and what we do is we take a base something and we decorate it let's go back to Starbucks right you start with some coffee and you're going to add some syrup you're going to add cream whipped cream change temperature all these different things that can affect the price yeah so instead of having one class for every single combination let's just have and I coffee interface or in this case an AI car interface and let's decorate the car so let's say I was watching some times already demo code what that means I will okay um but I also have to just say that I was watching the the remake of Speed Racer and I was watching this so hence the cars so I have a base car and it has a drive attack and defend basically a hit point value okay let's say I want to have an armored car the armored car drives a little slower attacks the same doesn't change from the base car but it defends much better okay all right let's go down and look at the race car obviously it's faster does an attack as well it's lighter doesn't defend as well and then an attack car right so we go through so if I'm building the classes to support making the movie speed racer this is very simple we could all do this we got different styles of cars okay but halfway through the movie speed racer says well I got a double armor it I'm going to tube up the engine and I'm going to put better guns on it well is just another class think about all the combinations that you would have to come up with right so what instead and create instead of creating a class for each of these options we decorate it the way we decorate it is let's look at the armored car is we all of them implement a car right which has Drive attack and defense and we pass in an AI car into the constructor and we're going to Decker we're going to armor this car we're going to put some more plating on it well because we're adding additional plating the drive speed decreases but the defense power increases and we're not modifying the attack vector okay if I look at the attack car we do the same thing we pass in an AI car and it doesn't drive quite as fast but it attacks much better and it defenses lower okay so I can take my base car factory standard and I'm going to pass it into an armored car decorator put some armor on it I'll undo it again put it back into an armored car decorator put some armor on it so what I'm doing is I'm creating these circles around okay so I'm going to zoom with an AI car this doesn't know this attack car decorator has no idea what the icon already has mm-hmm the trick here is that we're not setting values we're decorating the values right taking a little decoration off adding a little decoration taking the Thanksgiving decorations down putting the holiday decorations up right just change you're not changing your house right you're just decorating it okay so that's a phenomenal pattern I think especially because it would have saved me so much time writing the configurator if you didn't do that then you'd have to create a car and then you have to manually set all the properties right and remember what the rules were for setting the properties and now you've got just all those properties all in one place at the same point you created the car so you're not getting separation of concerns you're not getting much reusability right you're not getting any reusability and if I let's say I wanted really easy to mess up right and let's say I want to armor three times yeah well now I have to create yet another class right and remember that when I armor it it well this is the attacks I said okay so when I attack I increase it by 30 well what if I forget and then I crease it by 40 right right yeah so it's just a critical we go to next time you want to create a double armored car in a different part of your code you got a copy that code create the car again and then copy all of those properties yep or extract that into a method but now you've got multiple different methods for every time you wanted to do it differently yeah yeah and that's about the time that you update your resume for new job or you learn how to do this or you learn how to do this there's only couple more patterns okay the command pattern really really simple and I demonstrate how simple it is the command pattern always has a controller that calls the commands think of a remote control right you've got a remote control and probably says cable TV DVD or VCR if it's an older one and you push that button push the VCR button and the VCR turns on right which is again it turns off the remote control has no idea how to turn on that VCR right it sends a command yeah the VCR recognize the command is oh I need to do something with this so I'll turn it on right so here I have a very simple control option point this doesn't help your viewers so I'll point to this very simple controller I've got a light mm-hmm and I've got a light command the light command is very very simple it's just if the light is on and I execute it turns the light off right right first so you can also do undo but then what Sun do you have to track the commands are executed so this is just a very simple example and then the controller literally is just right Allah so these controls now remember when we talked about the factory pattern we had some commands bake cut box right when we talked about e-commerce pick pack ship charge your credit card those use commands so if you're controlling code doesn't have to know anything about that and says by the way they ordered this item go pick it right and and it gets sent to some other system innocent says oh here's this queue it's a book I can pick up manually you know or automated with a robot arm oh it's a thousand year old vase mm-hmm I'm going to send a human to go grab this very carefully in pulls over you're calling code has no idea okay what's going on right so now you've got separation concerns you've got single responsibility yeah I am responsible for picking this I'm responsible for pack I'm responsible for shipping right so we start combining these patterns together you get much cleaner code and much more extensible yes so now we're going to start selling boats on amazon.com which is a whole different style of delivery right but your UI the code that controls the commands and the workflow doesn't care mm-hmm right now I extend it I create this new set of commands and I can keep building onto my site very good all right the last one strategy so the strategy allows us to change the functionality is something at runtime I mentioned log4net earlier and we were talking about di and really it's a better example of the strategy pattern so the strategy pattern says I'm doing something I'm going to get some sort of input I'm going to do something different right log Fernet no logging now there's a problem on your production server I'm going to crank logging up to eleven which is performance but it gives me all those data then I can turn logging back off now go analyze the data right because one of the problems we always have is well it works on my machine I can't reproduce the problem right so what we're going to do here is we've got some superheroes they all have different powers so spider-man we all know wheeze webs Superman flies Batman fights and if I could do italics right because Batman would fight going old-school a little bit and they've all got these powers yeah and that's fine but let's let's go and look at Peter Pan not Peter Pan Peter Parker and so spider-man is going up to meet the bad guys uh-huh and he's shooting his webs and what happens as soon as he sees Mary Jane its web slinger jams right so he has to get a new superpower he can't go timeout I'm gonna go back to my aunt's house and change my superpower come back well if the bad guys are gonna be gone right so in the middle of the fight he has to switch what he's doing right and so whether it's me so now he has the new fight superpower and he doesn't really fly but you can jump off building and then if his web-slinger's working right he can yank oh so so this is this is awesome so to do zero code smell this video is probably been in here for about four years and every time I get this point I'm like I need to fix that and then I forget let's look about it so that's great right again we're not writing software about Rocky and Bullwinkle or Superman or spider-man but let's say we've got to go back to the ecommerce site right and there's a power outage on the East Coast and our cheese factories on the East Coast and the cheese is going to melt mm-hmm they're not melt go bad right and so we want to change the price of cheese without deploying all new release so through the strategy pattern and the commands right so pricing is one of the things so I'd say get me your price again your front end knows nothing about how the calculated prices right but cheese knows how to price itself it changed that capability at one time and we can do that through dependency injection so we can just create a new assembly or a new configuration really what do we do in real life we change database value but what are we doing we change the database value we're changing the way something operates at run time right so that's an example of using this pattern right and we only want to sail to go on until the power comes back on so when the power comes back on we want to immediately go back to our normal pricing okay and we don't want to again have to deploy a whole new site to do this we want to be able to do configuration through dependency inversion by OC containers be able to change things at runtime okay so that's the last one I have you to show today cool so do you have for each of these examples of the old way of doing it and then how you would do it once you adopt these patterns you do that you know that's a great idea I don't I don't have that what I think about what I what I recommend people do is get a book like the head first design patterns book and read them and go out to something like project Euler EU y le R which is just a bunch of math problems and program and just do Coty's code kata write practice writing the code delete it practice writing the code delete it because what we want you to get to is the point of where to borrow a matrix reference you won't be able to seize it the lady in the red dress one thing that I use design patterns for when I'm running teams is when we're talking about how to design a system I don't let people use our whiteboard because as soon as you give an engineer a dry erase marker and a whiteboard they're off drawing shapes and figures and naming things right and you get totally done rabbit hole but if we can just sit back and talk about well how would you build this it's a configurator well should we consider a decorator well yeah okay we want what's the next thing that we have to design right and so it becomes a language a way of communicating without going into all these great details so it just practice I don't have I you know what I'll probably add some examples of the bad way of doing things I won't say the bad the not is optimal way of doing things okay go back and look at a couple apps that I've built and see if we can come up with some examples and able to follow up show yeah we're actually show refactoring and I'm factoring right and then and then why yeah okay that'd be great cool well thanks for having me on the show again Hank's for coming on yeah all right I hope you find that very useful and let's make this the beginning of the conversation so good and we will see you next time on visual studio toolbox all right take care [Music]
Info
Channel: Microsoft Visual Studio
Views: 218,033
Rating: 4.8373494 out of 5
Keywords:
Id: agkWYPUcLpg
Channel Id: undefined
Length: 57min 17sec (3437 seconds)
Published: Fri Jan 13 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.