 Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me is Phil Jepixi. Hi, how are you? Phil, I'm good, how are you? Doing great. Thanks for having me back. This is the first in a series of sessions that we're going to do on design patterns. True. We did a kind of an overview while back, and we said we would have you back to do more and do them on an individual basis. Right. This is the start of that. Well, to start with an asterisk, right? So, the one that we just did with test run development kind is to kick off really. But then, yes, this is the start of the design pattern series. Right. Yep. And we're going to do a number of them. Yep. It's about 10. We're not 100 percent sure yet because we may do two patterns in one episode. Well, for example, the ones we're doing today. Okay. So, it'll be a bunch of them. We're going to start off with which ones? The command and momentum patterns. Okay. And then, before we do, let's talk about why we're doing this. What is it we want folks to learn? Yeah. So, design patterns basically are the result of other people having solved specific problems in the past. A great concrete example that I like to use because everybody understands that are doors. Right. Doors come in all shapes and sizes. Different functionality. Sometimes, there are fire doors. There might be screen doors. There might be pocket doors. But there are doors. The pattern that that's filling is providing an egress between two spaces that can be closed. So, that would be the design pattern concept. So, when you and I are talking about building something, building a house or remodeling the studio, you would say, I would like a door here. Right. Then, later, you'll have to figure out, does it need to be soundproof? Should it be able to lock those implementation details come out later? Okay. But you and I both know what we're talking about when you say I want a door there. Got it. Software design patterns are the same thing. So, instead of going into great detail when we're discussing how we're going to implement a particular feature, if we could talk about it in the design pattern level and figure out how we're going to solve the problem without getting stuck in the weeds, then you and I could both agree that, for example, you know, we need to build an e-commerce application and the main part of the application should use the command pattern to shell out to the specific implementations of charging a customer, picking inventory, packing and shipping. Okay. And we say, great, that's perfect. Let's use a command pattern for those and then we go off our separate ways and start working. Now, is that the only pattern that we're going to use? No, we're probably going to use more. But the goal is to be able to communicate, solve problems that have already been solved and make it easier to support. Years ago, I had gotten to take a vacation in France and this was like long enough that we didn't have cell plans over there, right? So, it was a fortune for me to talk on the phone and I had a lady who was backfilling for me and a customer and she was charged with fixing a production bug because I didn't have enough unit tests in place and she called and said, I don't understand what you're doing here on this form and I'm looking at my watch going, oh my gosh, this is hugely expensive and I said, oh, that screen, I used a strategy pattern for that and it was like a light bulb went off. She was, oh, okay, bye, have fun. And she hung up and then it's like she saw the lady in the red dress. I did a ones and zeros to borrow a reference in the matrix and so it's communication, but it's also standing on the shoulders of giants. Okay. Does that make sense? It does. Okay. So let's talk about the command pattern first. It's probably one of the easiest patterns out of the entire book. So the command pattern, and we'll do this through all of them. We've got the Wikipedia definition I want you guys to have or you guys to have, sorry. And then we will actually go into code and then talk about practical uses for it. But the key thing with the command pattern is it's used to encapsulate the information needed to perform an action or trigger an event at a later time. So let's just stick with trigger and action. You have a remote control at home, right? Sure. For electronics. And you and I are probably of the age that our remote controls have a VHS button in addition to it, maybe a DVR button. DVR, CD, SAT. Yep. Yeah, all those. So the remote control knows nothing about the DVR player, the satellite, the cable box, the TV. It just knows that when somebody pushes this button, it sends out a command. Right. And for most electronics, that command is a bit flag. If I'm on, turn me off. If I'm off, turn me on, right? And you have to program the remote control for your specific making manufacturer. You don't have a button for every single manufacturer or every single model number. You got just one button and you program that right. So the command pattern works the same way. You've got this controller, which could be remote control, could be a factory method or a template method, which our patterns we'll talk about later in this series, where it says charge the customer. And that is the command. You write the code, charges the customer, it's gonna ask them if they need Visa, you know, MasterCard, MaxPress, however they're gonna do it, right? But I, in writing this main method that calls the command to charge a customer, I don't need to know any implementation details, right? So that's the key thing. Now there's an optional aspect of command, it's the undo. So with the remote control, it's not really a good example for undo because you just pushed a button again and it turns on or turns off. But a great example of the command pattern with undo is, you know, the most famous keyboard combination that all developers use, which is of course control Z, right? I didn't mean to delete that, control Z. That's a command being set from the keyboard that goes into Visual Studio or Microsoft Word or whatever and reverses the last action done. So it's keeping track of what you did and then calling an undo on that. And so, you know, it's an optional part of the command. I could, you know, refund the customer is probably a different process. So the charge a customer might not make sense to have an undo. But to pick inventory to have an undo probably does make sense, right? Because you can put the inventory back right where you found it, right? So let's look at code. And as we discussed in the TDD episode, I use a lot of, I always write unit tests or try to. If I don't write unit tests before I write my code, I feel a little dirty. Doesn't mean that I never do, it just means sometimes I need to take long showers to clean myself up. But I find it much easier to describe how something behaves by using a unit test than trying to write a whole bunch of domain specific code to then show this one particular aspect. So here I have a controller. This would be like my remote control. I have an interface that represents a command. And in this case, it's an add numbers command. Now this is a very trivial example. I basically have a string builder that I am either adding text or numbers to and then I have the option of undoing the last command or the last series of commands. Is this something that you would do just like this in production? I hope not because it's like writing the Fibonacci sequence, right? We all learn it in school. I've never been paid to write the Fibonacci sequence for anybody. So it really is just sample code to demonstrate the principles. The controller has to know about the commands, right? There's some way I have to be able to push that button. This is you programming the remote by using that real fine print on the big remote control sheet to say I have a Visio TV, right? And you push in the right numbers. I then execute the command, passing in the value and that's probably not the best variable name for it. But the three hardest things in programming, don't you? It's off by one errors and naming conventions. Right. So then I just checked to make sure that the string builder is returning one, two, three, four. Right, so it's very simple. I'm basically just putting things on the end. But let's say I want to undo that. And we'll look at the code at how all this works shortly. So we want to undo same thing. Now before we move to undo, where's the command pattern in that? Oh, the point I was going to show you to undo then we're going to go into it, but you're probably right. This is a better order. So I have a base command which implements the I command. Now I do have comments in here all over the place. It's bad form to have more than one object in a file. But for teaching, it just makes it easier so it bounced back and forth. So my I app commands, and I just made up that name because command I command is actually taken by WPF. I have an execute and unexecute. And the execute takes in string. This is what we're adding. And unexecute doesn't take a parameter because it's just saying unwind the last thing I did. Right, if I had to pass in a parameter, it would be like control Z requiring me to type in what I wanted to undo in order to undo it. So I have a base command. And the reason I have a base command again for my silly example is to keep track of the string builder. Okay. And then I just make the execute and unexecute abstract. So my specific implementations of the commands have to take, have to implement them. So my add command or add text command, I have an execute, which just appends the text to the string builder. And then adds that text to a list of where I'm tracking the items I can undo. It's the same as in Visual Studio, you have 20 by default, I believe it's 20 undo operations you can do. Right. You can change that buffer, then it uses more memory, things like that. Now you'll notice, let's go back to the base command. Because I am keeping track in the base command, but not like a static command. The undo only works at that particular command level. So let's say I have an add text command and the add numbers command. And I add text and I add text and I add numbers and I add text. Then I want to undo the add numbers. Well, guess what? There's a bug in my program. Because it's going to undo the last operation, which was the add text. And when we talk about memento next in this episode, we'll talk about where we can restore states to a previous point in time. Okay. So we have to unwind the stack in this style of implementation one at a time. We can't jump to a previous point in time. Does that make sense? Sure. Okay. So here we have added a value to the string builder. We've popped that string onto the stack of undo operations. So now if you go back to the code. Which code? That code there. Yep. The fact that you are calling controller.add command is that the command pattern. Because you don't, this code doesn't know the implementation of what you're doing. So the execute, there it is. The execute is the implementation of the command pattern. What this is doing, this is you programming your remote control for your busy old TV. Right. Execute. So the fact that you have encapsulated this, you've taken that code out of this method and put it into a classic. I've completely encapsulated all of it, right? So the controller doesn't know about the string builder. Right. I could be adding stuff to a file. I could be adding, pushing stuff into a database. Any number of implementation details. In this code you've told your assistant to execute. This is basically the equivalent of having staff. Yes. Right? Yep. Go do something. Go execute. I don't need to know how you do it. Get it done. Just go do it, get it done. And I may want to know what the results were that it succeed, did it fail? Or go do something, tell me the results but I don't need to know how. Right. That's the command pattern. Exactly. In a nutshell. Okay. That is just picking which button to push. Right. On the controller. Yep. Now you might also want to tell your staff, ah, I told you prematurely to do that thing. Can you go undo it? Right. Right? And again, you don't care how. You just want them to go away and report back later. Yep. I've undone it. Call the fixer. Call the fixer. So this is the exact same thing pretty much. Executing, adding the one, two, three, four then I add a five, six, seven, eight. I then call un-execute which unwinds that five, six, seven, eight addition to the string. And then I verify that the string that I get back is the one, two, three, four which was the state prior to executing that command that I undid. Right. So, that is, like I said, it's a really simple pattern to code, but there's, as we were discussing over lunch, there's lots of implications about, well, is this really the command pattern or is this not the command pattern? So before we go back and go into the memento, it's kind of come back and redress this. Yeah, so let's use the example we were talking about. I'm writing a weather app, right? And I've got a UI, I've got a text box or it could be a dropdown. Some way of identifying the city, button to get the weather, and then one or more labels to display the results. In that button, I could put the code to call the weather service and do all the manipulations. I can put all the code in the code behind. Okay, let me stop you there. Because we did this for years with VB, right? And I'm not knocking VB, it was just kind of how we did things, right? You have a form, you double click on the button, you get the click event right there in the code behind and you start a coding stuff. Right, you put in the entire implementation in there. Okay, now push the button, call the weather service, label gets updated, everybody's happy. Then that weather service goes out of business. Now what do you do? Or you want to reuse that code somewhere else. Or reuse that code somewhere else. Either way, I have to go now and either clip or inherit that code somewhere else. Or I have to change that production code because I tightly coupled the command to the implementation. Right, so instead I create a weather class, weather service class, I usually call mine weather service. Okay. Because it is essentially a service. Yeah. And then in the code behind, var weather equals new weather service. Okay. Weather dot get weather, pass in whatever's in the text box, label dot text equals whatever that thing returns. Yes. Is that the command pattern? It is, but it's making me twitchy. Because I'm not using an interface. Because you're not using an interface. Do I have to use an interface for the command pattern? You do not have to use interface for the command pattern. Okay, now the fact that I should then think about for reasons we'll talk about later when we get to things like the factory method, I should do more encapsulation. What happens if the weather service changes, right? What happens if I want to have an online versus offline version for it? There are all kinds of good reasons why I wouldn't stick to that. Well, let me go back to our previous episode. If you say var foo equals new weather service in your button click, how are you gonna test that the button is actually calling the weather service? Let's say you're on an airplane and you have no internet connectivity and you push that button and the app just hangs. Where's the problem? Right, so then what I'd have to do is I could go into my weather service and have that call an interface, but that's just kind of kicking the can down the road. Or you probably should do that in the button. Or the button talks to an interface. Anytime, the phrase that commonly gets thrown out there, and I think it's a good one, new is glue, right? Good friend of mine, Steve Smith, who's really, really deep in the patterns and code quality uses that phrase a lot. And it's true. Once I say var foo equals new bar, then I am stuck to that implementation, or I have to go in and change code. If I code to an interface, and I'm not dependent on the implementation, so let's go back to testing that. We showed you how to use mox, MOQ, the framework, to create a mock, and it set up a expectation that a particular method gets called. So we can set up a test that where we pass in a mock of the eye weather service, set up that it calls get weather with a particular string or any string, and then we can verify it was actually called. So then in that button click method, we can write a test for that and say does it call the weather service yes or no, with the correct parameters yes or no, and if it does, we know we're good, right? So it just further encapsulates code, making it single responsibility, right, and separation of concerns, and it just enables all kinds of options that you don't have otherwise. Whether or not you do that. Whether or not you do that, it's still an implementation of the command path. It's still the command path. What we have done is we've encapsulated just what it says here. We've encapsulated all information needed to perform some function. Now sometimes people will look at it and say it's really only the command pattern if the command that you're calling manipulates some object, like so saving a record to a database versus going to get the weather, right, or making a change. I'm not saying I agree with this. I have had discussions with people at conferences and that's the beauty of command patterns, right? It really is just a guideline to a problem that's been solved before and you can implement it how you want. Right. It's a bit like the pirate code. It's more of a guideline than an absolute. Right. And then it becomes just a question of implementation. True. Now you're talking about what, you're almost talking about what type of door and not so much. The door pattern is that there is a way to get from room to room that can be closed behind you. Yes. Right? That's the pattern. That's the door pattern. So we could say that the command pattern is you encapsulate code, you call a method of something else. Yes. Now on top of that, there's additional techniques and they have their benefits and we can discuss when and why to do that. But it doesn't change the fact that you are following the pattern as it's basic level. Right. Okay. Yeah. And it's, again, the goal is to get that cleaner code base separation of concerns and single responsibility. Yep. The button, its only job is to phone home or phone that weather service. Yep. Don't even know what weather service. So it says, get me information. And then the weather service, and we can talk about the factory pattern, we will talk about the factory pattern in a later episode, can say, oh, which weather service would you like? Right. Right? And let me help you get the right weather service so then you can make that call. To MVVM, MVC essentially automatically put you into this because in the code behind all you're doing is calling a method of the view model. Right. Right. Well, and if you're doing WPF or XAML, absolutely, the way buttons work in WP, I'm sorry, XAML, it is absolutely the command pattern. Right. Yep. Cool. All right. Let's go on the memento. The memento pattern actually does stand on its own but it works really well with the command pattern as well. And what really matters is just that first sentence. Again, lots of words on here that your viewers can read at their leisure or they can pause on their computer and read it and not have to try and read it while I speak. But the memento pattern, easy for me to say, provides the ability to restore an object to its previous state. So it's an undo via rollback. Okay. Now, how this is different than the undo we just talked about. I was popping items onto a stack. Right. And then to undo, I was basically taking them off or pushing them on the stack and then popping them off and then changing the state that way. Yep. This is actually saying, what was the state of this subject prior to executing this command? Save that state, execute command. Right. So now I have this state, this state, this state, this state, this state and I can rollback to any one of these. Right. Now this is different than, for example, how NAD framework does it. So NAD framework, when you are tracking an object, you have the original values and the current values. And then of course you can make an additional calling it to database values, but that's kind of a different pattern. So I can undo, but the way EF has implemented it, which is perfect for that business case, undo says, get rid of everything, roll me back to the initial state. So it's kind of the memento in that standpoint, but it's not storing all these states along the way. There's a good reason for that. If it's storing all these states along the way, guess why I've just used up on your computer. Huge amount of memory. Huge amount of memory. Right. This space and it's also not, it's unintuitive. Right. Correct. I can't change the data until I save back to the database, right? If I'm in between, I'm undoing typing I've done. I've done. I haven't done the database, there's nothing to undo. So it totally makes sense that you would roll back to a save point. It's like checking in code, right? Roll back a commit. I don't roll back the code I typed. You can't roll back the code you've typed. You can only roll back commits. Right. But I can actually undo a particular change as part of a commit, right? Yeah, true. And so there's kind of that blend, right? I can get back to a previous state, but not the 27 things that I typed undo those, but keep the first 43 that I typed or something crazy like that, right? So it stands on its own, the momento does. And you have to really think about what's the business case for using it. Right. So if we look at this, and this is why I like talking about this with the command pattern because it's a great way to demonstrate it. You can usually tell the command pattern because something is gonna have the word command at the end of the name, of course, naming is hard. So I have a new customer object, very simple customer, two properties. And I have this change customer command and execute just changes the name. Again, very, very simple example, probably wouldn't even need a momento or a command to just change the name. I could just change the name, but I wanted to demonstrate the pattern. So then I assert that the name was changed. Yes. But here I want to do a rollback. So here I have the original name is John Doe. On line 29, I create a new customer. On line 30, I then change it or create the new change customer command. So those first four lines, five lines are essentially the same. The only difference is that I put the original name into a variable because I need it in my test. I then call execute name becomes Billy Bob, but then I call un-execute and I want that customer to be exactly the same as it was. So I could add an additional assert right here where I can say command that customer.id is five to show that I'm getting back that complete state. And this is where the momento kind of shines. If I had 30 properties on this customer object, which one could argue that's too big, but through here and there, and I had to return to some specific state. Does that mean I have to track for every single property on that object, the change history and the change history in relation to other changes? Well, I hope not. Right, so I've changed the name seven times. I've changed the id twice, which is evil. You should never change id, but that's, again, another story. And now I have to sync it up to whatever it was at this given point in time. Well, that's a lot of tracking and a lot of wasted effort. Whereas with the momento, I can say give me the state of the entire object at this point in time or back so many changes, right? Back seven changes. Doesn't matter if six of them were the name and one of them was the address. Remember when we talked about the simple command pattern in the undo, we had a problem with that, right? This fixes that. So let's look at how we do this. And again, it's simple command. I don't need to go into there. But I have, instead of a list of entries, I have these momento for customer entity classes. And that's what I'm tracking as opposed to specific changes. So when I change the customer before I change it, I add the current state into a momento object. Okay. And then I make the change. Now- And you don't just add the customer. I don't just add the customer. We'll talk about it in just a minute. But I will point out that this example can use up a lot of memory. Again, I just wanna show an example of how this works. One specific- You can write it to the disk if you are concerned about that. Yeah, there's a number of ways to do that. So let's look at what a momento is. So momento is just a way of maintaining state for an object at a point in time. You had said a great point and you're almost like a big man leading me right into what I was gonna say. Of you younger viewers, well, never mind. If I just save the customer, the customer is just a pointer to a variable on the heap. Right. So if I'm saving these customer variables, then they will get changed along with the customer. So I actually have to create a clone of that customer and save that in order to get back to the state that I was in. So in this example, the customer knows how to make a clone of itself as all .NET objects do. So get customer just returns the customer. But you see when I create a new momento, it is actually just storing a clone of the customer at that given point in time. And the customer class just returns a member-wise clone. Okay. To get to clone. Cool. So let's look at the undo and how that works. So instead of changing the underlying targets, when I undo, it says get me the last momento. That you saved. That I saved. Yep. I saved the customer as it was in that momento and then I removed the momento from the list. This also gives you the ability to go get the customer as it was before you made changes without necessarily removing it from the stack. Yeah, that's true. You could also say. If that was something you chose to do. Yeah. Right. Find, add, and change. I mean, you can think of that in terms of source control, right? Right. Because I can look at the current file and look at different change sets to see the delta over time. Yep. Yep. Cool. So that's a command in mode. Yeah. And people are probably already using it. Probably. And they didn't even know it. Well, maybe not the momento. I'm pretty sure they're using the commands. Maybe not the momento, but certainly the command. Yeah. Just got to remember to encapsulate that logic. Yep. News, glue, and you want to keep that separate so you can support it better. All right. Awesome. Great. All right. Good start to the series. Yeah. Can't wait for the rest. See you then.