Concept:
Command mode, also known as the order mode, is one of the behavioral design patterns. Command mode encapsulates the invocation behavior of the target object and the invocation parameters through a class called command.
Command pattern is a data-driven design pattern that belongs to the behavioral pattern. The request is wrapped in an object as a command and passed to the calling object. The calling object looks for the appropriate object that can handle the command and passes the command to the appropriate object, which executes the command.
Main solution:
In a software system, the "behavior requestor" and "The behavior realization person" usually present a kind of "tight coupling". However, in some cases, such as "record, Undo/Redo, transaction" and so on, this can not resist the change of tight coupling is inappropriate. In this case, how do you decouple the "behavior requestor" from the "behavior-implementing Person"? Abstracts a set of behaviors into objects, implementing two
The loose coupling between them. This is the command pattern.
Below, give a small example, but not implemented using the command pattern
Create a new Peddler class, a small trader who sells fruit.
1 /*2 * Small Traders3 */4 Public classPeddler {5 /*6 * Sell Apples7 */8 Public voidsailapple () {9System.out.println ("Selling Apples");Ten } One A /* - * Sell Bananas - */ the Public voidSailbanana () { -SYSTEM.OUT.PRINTLN ("Selling Bananas"); - } -}
Build a client again
1 Public class MainClass {2 Public Static void Main (string[] args) {3 New peddler (); 4 peddler.sailapple (); 5 Peddler.sailbanana (); 6 }7 }
Results:
Application Scenarios for Command mode
In object-oriented program design, one object calls another object, in general the calling procedure is to create the target object instance, set the invocation parameters, invoke the method of the target object (as in the example MainClass, create the Peddler instance, and then dispatch the method).
In some cases, however, it is necessary to encapsulate this invocation process with a specialized class, which we call the command class.
1, the entire call process is more complicated, or there are many such calls. At this point, the command class is used to encapsulate the call and facilitate the reuse of the function.
2. Some processing of call parameters is required before and after the call.
3, before and after the call to do some additional processing, such as log, cache, record history operations.
Structure of the command pattern
Role and responsibilities of the command pattern
1. Command: Command abstract class, which defines the interface of the commands, declares the method of execution:
2, Concretecommand: command of the implementation of the specific class, the implementation of commands interface object, is "virtual" implementation, usually hold the receiver, and invoke the function of the receiver to complete the operation of the command to do.
3. Receiver: the target object that needs to be called, the receiver, the object that actually executes the command. Any class can become a recipient, as long as it can implement the appropriate functionality that the command requires.
4. Invorker: The Command object is executed by Invorker, which requires the commands to execute the request, usually holds the Command object and can hold many command objects. This is where the client actually triggers the command and asks the command to perform the appropriate action, which is equivalent to using the Command object's entry.
5. Client: Create a specific command object and set the recipient of the Command object. Note that this is not our regular client, but the assembly of the Command object and the receiver, and perhaps it would be better to refer to this client as the assembler, since the client that actually uses the command is triggering execution from Invoker.
Of course, our example is very simple, we do not use the command mode, we assume that the operation is very complex, using the command mode to transform
First, create a class to encapsulate the calling procedure, first creating a command abstract parent class
1 Public Abstract classCommand {2 //contains a reference to a Receiver 3 Privatepeddler peddler;4 5 PublicCommand (peddler peddler) {6 Super();7 This. peddler =peddler;8 }9 Ten Publicpeddler Getpeddler () { One returnpeddler; A } - - Public voidSetpeddler (peddler peddler) { the This. peddler =peddler; - } - - Public Abstract voidsail (); +}
Next we create the concretecommand, we create one for each operation, so we're going to create two apple and banana
1 /*2 * Apple3 */4 Public classApplecommandextendscommand{5 6 PublicApplecommand (peddler peddler) {7 Super(peddler);8 }9 Ten @Override One Public voidsail () { A //You can also do extra work around this sentence. - This. Getpeddler (). Sailapple (); - } the -}
1 /*2 * Banana3 */4 Public classBananacommandextendscommand{5 6 PublicBananacommand (peddler peddler) {7 Super(peddler);8 }9 Ten @Override One Public voidsail () { A //You can also do extra work around this sentence. - This. Getpeddler (). Sailbanana (); - } the -}
Finally, modify the MainClass
1 Public classMainClass {2 Public Static voidMain (string[] args) {3Peddler Peddler =Newpeddler ();4Command Applecommand =NewApplecommand (peddler);5Command Bananacommand =NewBananacommand (peddler);6 7 Applecommand.sail ();8 Bananacommand.sail ();9 Ten } One}
But this is not good enough, you can see this is directly from the command to call the sail method, so bad, we want to be sold by a person, just like someone hired a waiter, so we create a new Invorker
Public class Waiter { private command command; Public Command GetCommand () { return Command; } Public void setcommand (Command command) { this. Command = command; } Public void sail () { command.sail (); }}
And then modify the client
1 Public classMainClass {2 Public Static voidMain (string[] args) {3Peddler Peddler =Newpeddler ();4Command Applecommand =NewApplecommand (peddler);5Command Bananacommand =NewBananacommand (peddler);6 7Waiter Waiter =Newwaiter ();8 Waiter.setcommand (applecommand);9 Waiter.sail ();Ten One Waiter.setcommand (bananacommand); A Waiter.sail (); - - } the}
So that the Client can speak directly to Invorker .
We can only add commands now, but we can't remove the commands, and we can only have one command at a time, we continue to transform
1 Public classWaiter {2 PrivateMap<string,command>commands;3 4 PublicMap<string, command>getcommands () {5 if(Commands = =NULL){6commands =NewHashmap<string,command>();7 }8 9 returncommands;Ten } One A Public voidSetCommand (String key, Command command) { - if(Commands = =NULL){ -commands =NewHashmap<string,command>(); the } - commands.put (key, command); - } - + Public voidRemovecommand (String key) { - Commands.remove (key); + } A at Public voidSail (String key) { - Commands.get (key). Sail (); - } -}
Client
1 Public classMainClass {2 Public Static voidMain (string[] args) {3Peddler Peddler =Newpeddler ();4Command Applecommand =NewApplecommand (peddler);5Command Bananacommand =NewBananacommand (peddler);6 7Waiter Waiter =Newwaiter ();8Waiter.setcommand ("Apple", Applecommand);9Waiter.setcommand ("Banana", Bananacommand);Ten OneWaiter.sail ("Apple"); AWaiter.sail ("Banana"); - -Waiter. Removecommand ("Apple"); the - } -}
So, it's done, an example of a command pattern
Advantages and Disadvantages of command mode
Advantages: 1, reduce the system coupling degree.
2. New commands can be easily added to the system.
Cons: using command mode may cause some systems to have too many specific command classes.
Java design mode-----23, Command mode