- Overview
- Transcript
4.2 Command
Power! This pattern does just that: issues a command. But it's a bit more complicated than that. You'll learn how it works in this lesson.
1.Introduction1 lesson, 01:40
1.1Introduction01:40
2.Creational Patterns2 lessons, 11:52
2.1Factory05:30
2.2Singleton06:22
3.Structural Patterns4 lessons, 33:47
3.1Adapter07:08
3.2Composite11:33
3.3Decorator08:02
3.4Facade07:04
4.Behavior Patterns4 lessons, 36:32
4.1Chain of Responsibility12:12
4.2Command07:34
4.3Observer09:28
4.4Strategy07:18
5.Conclusion1 lesson, 01:06
5.1Conclusion01:06
4.2 Command
The command pattern is one of those that is aptly named. Because what we do is we create a command and we execute that command. But it's a little bit more complex than that, because we essentially have three parts to the command pattern. We have the command itself. That is going to encapsulate some kind of functionality on what is called the receiver. So the receiver is what is going to receive the command, and then we have what's called the invoker, or the requester. The requester is going to issue a command. And it doesn't know what that command is. It doesn't know what that command does. All it knows is that it is going to execute a command that will be sent to the receiver. So it's a way of decoupling functionality from the invoker or the requester with the receiver. And it helps if you remember i before e except after c. Okay so the whole thing centers around an interface called ICommand. And the command interface has a single method called execute. Now, this is extremely common across all languages. Any command is typically going to have a method called execute. And most of the time that execute method does not accept any parameters. You will find some implementations that do allow parameters to be passed to the command. But for the most part you will simply see an execute method that does not accept any parameters. That means that the command needs to have everything available In order for it to execute. So that means whenever we actually create our commands, we're going to pass information to the constructor so that it knows then what to do. So we are going to use the example of a television. So in our case a television is going to be the receiver that is going to receive the command. Then we will have the invocker or the requester. Whatever term that you want to use. And this is going to be the remote control. So we will have the remote, the remote doesn't really know what it's going to be issuing. All it knows that it's going to be issuing commands to something. It doesn't even know that it's going to be to the TV. And then we will have our commands. So lets start by adding some functionality to the television. We'll just have two methods. The first is going to be called turn on so that we can turn on the television, and then one for turning off. But we could also have commands for raising and lowering the volume, changing the channel, and so on and so forth. So in this method we are simply going to say "Television: " and then turnOff. Or no turnOn, because this is the turnOn method, and then we will have function turnOff, which will echo "Television: and turn off". So, this is the functionality that we are then going to encapsulate within the command. So let's write a command, and we'll call this the PowerOnCommand. So PowerOnCommand, so this PowerOnCommand needs to implement our ICommand interface, so we will go ahead and do that, and we will go ahead and add that method. So we will have execute. Now in order for us to execute powering on a television, we need to know what that television is. So we're going to store our $tv object in a private field, and we will get that television through a constructor. So we are going to accept a television and we'll just call that $tv. And then we'll say $this >tv = our $tv so that inside of our execute method, we are going to say $this->tv = $tv, so that's inside of the turnOn, and that is our command. So when it comes to the remote control, we don't know what the TV is, we don't really know anything except that we are going to be accepting a command and we're going to be executing that command. So we're going to store the command that we receive so that we can set the command and then execute it. So we'll have two methods. The first is called setCommand where we accept an Icommand, and we will store that within our command field. So we'll go ahead and set that up and then we will have a method and we'll just call it pressButton, we don't accept any parameters for this method, instead all we do is use our command that we have stored. And we will use its execute() method, and with all of that we just need to write our client code. So we will have our television first of all so let's new up television();, we also want to create our remote, so let's new up RemoteControl();. And then let's new up our $powerOnCommand, and that is our new PowerOnComand and we need to pass in our reference to our television object. So that now we say $remote, we set the command and then we pass in our ($powerOnCommand) and then we press the button, so PressButton. And if we hop on over to the console. That's php command, and hopefully there we see television turn on. So the idea here is that now that we have this command structure set up, we can create as many commands as we want and then issue them through the remote control. So let's create a powerOffCommand. So we're just going to copy and paste what we have and we will set the execute method to call the turnOff(); method on our television. So now we can create another command object. So $powerOff command, we would need to new up power off command. And then after we turn on the TV, we're just going to turn around and turn it back off. So let's copy that code, paste it. We'll change the name of the command that we pass in to it. So now we should see Television: turn on and then Television: turn off. Although we should have added some line breaks there, but that's the idea. If we had methods on our television to set the channel or to change the volume, then we could create commands for those methods, and then issue those commands through the remote control. Now there's an issue with the command pattern and that is, you can end up with a lot of command classes. And that can make your implementation look cluttered, and it also requires a lot of knowledge on the users part to know which command to use. So if you find yourself creating a lot of command classes, then there might be another pattern better suited for your purpose.