Command mode for Head first design mode (Commandpattern)

Source: Internet
Author: User

Preface:

This chapter takes the encapsulation into a whole new realm and encapsulates the method invocation. By encapsulating the method call, the operation block is packaged and formed. The object that calls this operation does not need to know how it is done, but it is OK to know how to do it using the method of wrapping.

1 real-world scenario applications

Now there is a remote control, the remote control has 7 slots to be programmed, you can put a different device on each slot, and then control it with a button, these seven slots have their own "on" "Off" button, there is a whole use of the undo button, will undo the last button action.

1.1 Creating the first Command object 1.1.1 defining a command interface

Public Interfacecommand    {        void Execute ();    }

1.1.2 Implement a command to turn on the light

Publicclass Light//Lamp class    {public        void on ()        {            System.Console.WriteLine ("Lights are on  !");        }        public void Off ()        {            System.Console.WriteLine ("Light is OFF!");}    public class lightoncommand:command//implementation of the lights command    {        private light;        Public Lightoncommand (Light)        {            this.light = light;        }        public void Execute ()        {light            . On ();        }          }

1.1.3 Using Command objects

public class Lightcontrol    {        Privatecommand soft;        publicvoid setcommand (command cmd)        {            soft= cmd;//set Command object        }        publicvoid buttonwaspressed ()        {           Soft. Execute ();//method that invokes the command object        }}

1.1.4 Simple test

Lightcontrol Lightcontrol = new Lightcontrol ();//The caller of the analog command lightlight = new Light ();//Create a Lamp object as the receiver of the command Lightoncommand Lightoncommand = new Lightoncommand (light);//Create a command and pass the recipient to it Lightcontrol.setcommand (Lightoncommand);// Pass the command to the caller lightcontrol.buttonwaspressed ();//Analog Trigger button

1.2 Implementing the remote control

public class Remotecontrol {command[] oncommands;//definition Open command array command[] offcommands;//define closed command array p            Ublic Remotecontrol () {oncommands = new command[7];            Offcommands = new Command[7];            Command Nocommand = Newnocommand (); for (int i = 0; i < 7; i++) {Oncommands[i] = nocommand;//Initialize command Array (default is no command) of            Fcommands[i] = Nocommand;            }}//Set the command to the corresponding controller public void SetCommand (int index,command oncommand, command Offcommand) {            Oncommands[index] = OnCommand;        Offcommands[index] = Offcommand; }//Trigger open Controller public void onbuttonwaspressed (int index) {Oncommands[index].        Execute (); }//Trigger off Controller public void offbuttonwaspressed (Intindex) {Offcommands[index].        Execute (); } public override string ToString () {StringBuilder str = newStringBuilder (); Str.            Append ("\ n------remotecontrol------\ n"); for (int i = 0; I <onCommands.Length; i++) {str. Append ("[Solt" +i + "]" + oncommands[i]. GetType (). FullName + "" +offcommands[i]. GetType ().            FullName + "\ n"); } return str.        ToString (); }    }

1.3 Implementing other Controllers

 Turn off the lights command public Classlightoffcommand:command {Privatelight light;        Publiclightoffcommand (light) {this.light = light; } publicvoid Execute () {light.        Off (); } publicvoid Undo () {light.        On ();        }}//Open the Fan command public class Ceilingfanoncommand:command {Ceilingfan ceilingfan;        Intprespeed;        Publicceilingfanoncommand (Ceilingfan ceilingfan) {this.ceilingfan = Ceilingfan;        } publicvoid Execute () {Ceilingfan.on ();        } publicvoid Undo () {Ceilingfan.off ();        }}//Turn off the fan command public Classceilingfanoffcommand:command {Ceilingfan Ceilingfan;        Publicceilingfanoffcommand (Ceilingfan ceilingfan) {this.ceilingfan = Ceilingfan;        } publicvoid Execute () {Ceilingfan.off (); } publicvoid Undo () {CeilIngfan.on ();        }}//Open the garage door command public Classgaragedooroncommand:command {Garagedoor Garagedoor;        Publicgaragedooroncommand (Garagedoor garagedoor) {this.garagedoor= garagedoor;        } publicvoid Execute () {Garagedoor.on ();        } publicvoid Undo () {Garagedoor.off ();        }}//close the garage door command public Classgaragedooroffcommand:command {Garagedoor Garagedoor;        Publicgaragedooroffcommand (Garagedoor garagedoor) {this.garagedoor = Garagedoor;        } publicvoid Execute () {Garagedoor.off ();        } publicvoid Undo () {Garagedoor.on ();        }}//Open cd command public Classsterecdoncommand:command {STERECDSTERECD;        Publicsterecdoncommand (Sterecd sterecd) {this.sterecd = STERECD;        } publicvoid Execute () {Sterecd.on (); } publicvoid UnDo () {Sterecd.off ();        }}//Close the CD command public Classsterecdoffcommand:command {STERECDSTERECD;        Publicsterecdoffcommand (Sterecd sterecd) {this.sterecd = STERECD;        } publicvoid Execute () {Sterecd.off ();        } publicvoid Undo () {Sterecd.on (); }    }

1.4 Simple test

Remotecontrolremotecontrol = new Remotecontrol ();             Ceilingfan Ceilingfan = Newceilingfan ("Living");//Create fan object Garagedoor Garagedoor = Newgaragedoor ();//Create garage door object STERECD STERECD = new STERECD ();//Create a CD Object light = new Lights ();//Create Lamp object Lightoncommand Lightonco Mmand = Newlightoncommand (light);//Create the Turn-on command Lightoffcommand Lightoffcommand =new Lightoffcommand; Create a light off command Ceilingfanoncommandceilingfanon = new Ceilingfanoncommand (Ceilingfan); Create an open fan command ceilingfanoffcommand ceilingfanoff= new Ceilingfanoffcommand (Ceilingfan);//create off Fan command garaged Ooroncommand Garagedooron =new Garagedooroncommand (Garagedoor);//Create Open Fan command Garagedooroffcommand garageDoorOff= n EW Garagedooroffcommand (Garagedoor);//create close fan command Sterecdoncommand Sterecdon = Newsterecdoncommand (STERECD);//Create Open cd command Sterecdoffcommand Sterecdoff = Newsterecdoffcommand (STERECD);//Create close CD command Remotecontrol.setcomman D (0,lightoncoMmand, Lightoffcommand);//Set the light command to the corresponding controller Remotecontrol.setcommand (1,ceilingfanon, Ceilingfanoff); Set the light command to the corresponding controller Remotecontrol.setcommand (2,garagedooron, Garagedooroff); Set the garage door command to the corresponding controller Remotecontrol.setcommand (3,sterecdon, Sterecdoff);           Set the CD command to the corresponding controller remotecontrol.onbuttonwaspressed (0);           remotecontrol.offbuttonwaspressed (0);           remotecontrol.onbuttonwaspressed (1);           remotecontrol.offbuttonwaspressed (1);           Remotecontrol.onbuttonwaspressed (2);           Remotecontrol.offbuttonwaspressed (2);           Remotecontrol.onbuttonwaspressed (3); Remotecontrol.offbuttonwaspressed (3);

1.5 Implement Undo Command 1.5.1 Modify command interface, add Undo () method

Public Interfacecommand    {        void Execute ();        void Undo ();//New Undo Method}

1.5.2 Modify the command to implement the Undo method


public class Lightoncommand:command    {        private light light;        Public Lightoncommand (Light)        {            this.light = light;        }        public void Execute ()        {light            . On ();        }        public void Undo ()//Implement Undo method        {Light            . Off ();         }}

Other classes are modified in turn

1.5.3 Modify Remotecontrol class, add Command object record previous action

public class Remotecontrolwithundo {command[] oncommands;        Command[] Offcommands; commandundocommand;//creates a command object used to record commands executed in the previous step Publicremotecontrolwithundo () {oncommands = new Comm           AND[7];           Offcommands = new Command[7];            Command Nocommand = new Nocommand ();               for (int i = 0; i < 7; i++) {oncommands[i] = Nocommand;            Offcommands[i] = Nocommand;        } Undocommand = Nocommand;        }................. publicvoid onbuttonwaspressed (int index) {Oncommands[index].           Execute (); Undocommand = oncommands[index];//record Open command} publicvoid offbuttonwaspressed (int index) {OFFC Ommands[index].           Execute (); Undocommand = offcommands[index];//record Close command} publicvoid undobuttonwaspressed ()//Perform undo {Undoc Ommand.        Undo (); } ...... ...... }

1.6 Macro Commands

Let the remote control have party mode, that is, a button can synchronously invoke multiple commands, this is called Macro command.

public class Macrocommand:command    {        command[] commands;//defines the command array to receive the incoming command public        Macrocommand (command[ ] commands)        {            this.commands = commands;        }        public void Execute ()//batch processing multiple commands (that is, an array of commands passed in at initialization time)        {for            (int i = 0; I <commands. Length; i++)                Commands[i]. Execute ();        }        public void Undo ()        {for            (int i = 0; I <commands. Length; i++)                Commands[i]. Undo ();        }    }

2 Defining the command pattern

The command pattern encapsulates "requests" into objects so that different requests, queues, or logs can be used to parameterize other objects. The command mode also supports the revocable operation.

To define a command pattern class diagram:


3 more uses of the command mode 3.1 queue requests

command to package the operation block, and then spread it, even after the command object has been created for a long time, the operation can still be called, and even can be called in different threads, we can use this feature to derive the application, such as: daily arrangement, thread pool, task queue and so on.

The work queue class is completely decoupled from the object being evaluated. They can be placed inside the queue as long as they are objects that implement the command pattern, and invoke the Execute () method of the object when the thread is available.

3.2 Log Requests

Some applications require that we log all actions to the logs, and after the system freezes, recall these actions back to their previous state, which is supported by the command pattern.

There are many action applications that call large data structures that cannot be stored quickly every time a change occurs, and by using logging, we can record all the actions after the last checkpoint and, if the system is present, you can apply them from checkpoints. For more advanced applications, these techniques can be extended to transactional processing, where a whole group of operations must be completed or nothing is done.

3 Summary

The command mode decouples the object that makes the request and the object that executes the request.

The decoupling between the two is communicated through the Command object, which encapsulates the receiver and a set of actions.

The caller makes a request by invoking execute () of the Command object, which causes the receiver's action to be invoked.

The caller can receive commands as arguments, even dynamically at run time.

The l command can support revocation by implementing an undo () method to return to the state before execute () is executed.

The macro command is a simple extension of the command that allows multiple commands to be invoked, and the macro method can also support revocation.

The L command can also be used to implement log and transaction systems.

Head First design mode command mode (commandpattern)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.