Encapsulation call: Encapsulate method calls.
This time we talked about the command mode. Its function is to encapsulate the method and call it when needed. The caller does not need to care how it is implemented.
Let's look at a flowchart.
Note:
1. The order encapsulates the request to prepare the meal.
2. The waitress's job is to accept the order and then call the orderUp method of the order. The waitress doesn't care what the order content is. She just calls the orderUp method.
3. The cook is an object. He really knows the specific content of the meal. Once the waitress calls the orderUp method, the cook takes over and realizes the specific method of the meal. Here the cook and the waitress are decoupled. The order encapsulates the details of the meal. She just calls the method of each order, and the cook knows what to do when she sees the order.
Okay, I redrawn a diagram to reflect the command pattern as follows, the process is the same as the above.
OK, we have a basic understanding of how command mode works.
Here's an example of Demo that simulates the action of a remote control to turn on lights and doors
1. Categories of writing lamps and doors
Electric light
package Entity; public class Light { public Light() { } public void on() { System.out.println("The lights are on."); } public void off() { System.out.println("The lights went out."); } }
door
package Entity; public class Door { public Door() { } public void OpenDoor() { System.out.println("The door opened."); } public void OffDoor() { System.out.println("The door is closed."); } public void StopDoor(){ System.out.println("The door stopped."); } public void DoorLightOn(){ System.out.println("The light in the door is on."); } }
2. Creating Command Interface
package Interface; /** * Command interface * * @author Joy * */ public interface Command { // Command Execution Method public void execute(); }
3. Implement a command to turn on the light
package Implements; import Entity.Light; import Interface.Command; public class LightOnCommand implements Command { Light light; // Input of a lamp type in the constructor // So that this command can be controlled and recorded in the light instance variable. // When execute is called, light executes different lighting methods depending on the type. public LightOnCommand(Light light) { this.light = light; } // Executing the Lighting Method @Override public void execute() { light.on(); } }
The Method of Implementing the Gate
package Implements; import Entity.Door; import Interface.Command; public class DoorOpenCommand implements Command { Door door; public DoorOpenCommand(Door door) { this.door = door; } @Override public void execute() { door.OpenDoor(); } }
4. Call Command Object (Remote Controller)
package Control; import Interface.Command; /** * Simple Remote Controller *Equivalent to caller * @author Joy * */ public class SimpleRemoteControl { // Command object type, equivalent to a slot controlling a device Command slot; public SimpleRemoteControl() { } // This method is used to set commands for slot control // If the customer needs to change the behavior of the remote control button, this method can be called many times. public void setCommand(Command command) { slot = command; } // Execution method public void buttonWasPressed() { slot.execute(); } }
5. Test class (using remote control)
package TestMain; import Control.SimpleRemoteControl; import Entity.Door; import Entity.Light; import Implements.DoorOpenCommand; import Implements.LightOnCommand; public class LightTestMain { public static void main(String[] args) { // The remote controller is the caller of the command, and it passes in a command object that can be used to send requests. SimpleRemoteControl remote = new SimpleRemoteControl(); // Create a lamp object, which is the recipient of the request Light light = new Light(); Door door = new Door(); // Create a class that turns on the lamp action and pass it to the receiver (light) LightOnCommand lightOn = new LightOnCommand(light); DoorOpenCommand doorOpen = new DoorOpenCommand(door); // Command to caller (remote control) remote.setCommand(lightOn); // Simulate push button remote.buttonWasPressed(); remote.setCommand(doorOpen); remote.buttonWasPressed(); } }
Design sketch
This is a basic command mode. It's a small try with a bull's knife.
Command pattern definition: encapsulating "requests" into objects to use different requests, queues, or logs To parameterize other objects, command mode also supports revocable operations.
Here's a class diagram of this pattern
Next, continue to simulate a remote control, but this time the requirements become more complex.
The example diagram is as follows.
Does each slot of the remote control correspond to a command, so that the remote controller becomes a "caller"? When the button is pressed, the execute method of the corresponding command object will be called. As a result, the actions of the receiver (e.g. lights, ceiling fans, audio) will be called.
Code start
1. Entity class
Electric light
package Entity; public class Light { //Location String location; public Light(String location) { this.location = location; } public void on(){ System.out.println(location+"The lights are on."); } public void off(){ System.out.println(location+"The lights are off."); } }
sound
package Entity; /** * Sound class * * @author Joy * */ public class Stereo { //location A location Variable String location; public Stereo(String location) { this.location = location; } public void on(){ System.out.println(location+"Audio start"); } public void off(){ System.out.println(location+"Audio closes"); } public void setDVD(){ System.out.println(location+"Play one on the stereo DVD And play"); } public void setCD(){ System.out.println(location+"Play one on the stereo CD And play"); } public void setRadio(){ System.out.println(location+"The sound is played in radio form."); } public void setVolume(int volume) { System.out.println(location + " Audio volume set to " + volume); } }
television
package Entity; public class TV { String location; int channel;//television channel public TV(String location) { this.location = location; } public void TVOn(){ System.out.println(location+"The TV turned on automatically."); } public void TVOff(){ System.out.println(location+"The TV shuts down automatically."); } //TV Channel public void setTVChannel(int channel){ this.channel=channel; System.out.println(location+"TV set automatically"+channel+"channel"); } }
2. Creating Command Interface Objects
package Interface; public interface Command { //implement public void execute(); //Revoke public void undo(); }
3. Implementing remote control class (caller)
package Control; import Implements.NoCommand; import Interface.Command; /** * Realize remote control * * @author Joy */ public class RemoteControl { // At this point, the remote control will handle seven switch controls, using arrays. Command[] onCommands = new Command[7]; Command[] offCommands = new Command[7]; // To revoke, of course, you need to know the previous order first. // Undo variables to track last invoked commands Command undoCommand; // Initialize the remote control class. Initially, the noCommand is an unoperated object. // When testing the output, the slot for the command is not explicitly specified, and the command defaults to the noCommand object. public RemoteControl() { Command noCommand = new NoCommand(); for (int i = 0; i < onCommands.length; i++) { onCommands[i] = noCommand; offCommands[i] = noCommand; } undoCommand = noCommand; } /** * * @param slot * :Location of slots (similar to index values) * @param onCommand * : Open order * @param offCommand * : Close commands These commands are recorded at the slot position corresponding to the switch array for easy use */ public void setCommand(int slot, Command onCommand, Command offCommand) { onCommands[slot] = onCommand; offCommands[slot] = offCommand; } /** * The switch button is responsible for calling the corresponding method at the corresponding slot position. * Different types of lights can be controlled by different positions of the switch button on the remote controller. * undoCommand: When we press the remote control button, we take this command and record it in undo Command. * @param slot */ public void onButtonWasPushed(int slot) { onCommands[slot].execute(); undoCommand=onCommands[slot]; } public void offButtonWasPushed(int slot) { offCommands[slot].execute(); undoCommand=offCommands[slot]; } //Add a Undo button public void undoButtonWasPushed(){ //Revoke undoCommand.undo(); } // Print each slot and its corresponding commands @Override public String toString() { StringBuffer sbf = new StringBuffer(); sbf.append("\n======================Remote control======================\n"); for (int i = 0; i < onCommands.length; i++) { sbf.append("[slot" + i + "]" + onCommands[i].getClass().getName() + "\t" + offCommands[i].getClass().getName() + "\n"); } return sbf.toString(); } }
4. Implement each command (7)
package Implements; import Entity.Light; import Interface.Command; public class LightOffCommand implements Command { //Specific object variables Light light; public LightOffCommand(Light light) { this.light = light; } @Override public void execute() { light.off(); } @Override public void undo() { light.on(); } }
package Implements; import Entity.Light; import Interface.Command; public class LightOnCommand implements Command { // Specific object variables Light light; public LightOnCommand(Light light) { this.light = light; } // Execute the method of turning on the light @Override public void execute() { light.on(); } // Revoke the operation and turn off the light @Override public void undo() { light.off(); } }
package Implements; import Interface.Command; public class NoCommand implements Command { // This is a non-operational class, and the class in the slot goes without instantiation. @Override public void execute() { } @Override public void undo() { // Method stub for TODO automatic generation } }
package Implements; import Entity.Stereo; import Interface.Command; public class StereoOffCommand implements Command { // Specific object variables Stereo stereo; public StereoOffCommand(Stereo stereo) { this.stereo = stereo; } public void execute() { stereo.off(); } @Override public void undo() { stereo.on(); } }
package Implements; import Entity.Stereo; import Interface.Command; /** * acoustic * * @author Joy * */ public class StereoOnWithCDCommand implements Command { // Specific object variables Stereo stereo; public StereoOnWithCDCommand(Stereo stereo) { this.stereo = stereo; } // Specific implementation method (method calls implementation method again) public void execute() { stereo.on(); stereo.setCD(); stereo.setVolume(11); } @Override public void undo() { stereo.off(); } }
package Implements; import Entity.TV; import Interface.Command; public class TVOffCommand implements Command { TV tv; public TVOffCommand(TV tv) { this.tv = tv; } @Override public void execute() { tv.TVOff(); } @Override public void undo() { tv.TVOn(); } }
package Implements; import Entity.TV; import Interface.Command; public class TVOnCommand implements Command { TV tv; public TVOnCommand(TV tv) { this.tv = tv; } @Override public void execute() { tv.TVOn(); tv.setTVChannel(15); } @Override public void undo() { tv.TVOff(); } }
5. Test class
package TestMain; import Control.RemoteControl; import Entity.Light; import Entity.Stereo; import Entity.TV; import Implements.LightOffCommand; import Implements.LightOnCommand; import Implements.StereoOffCommand; import Implements.StereoOnWithCDCommand; import Implements.TVOffCommand; import Implements.TVOnCommand; public class TestMain { public static void main(String[] args) { // Instantiated remote controller RemoteControl remoteControl = new RemoteControl(); // Instances need to control objects and pass them into the house location Stereo stereo = new Stereo("A living room"); Light light = new Light("A living room"); TV tv = new TV("Bedroom"); // Calling Device Switching Method StereoOnWithCDCommand stereoOnWichCD = new StereoOnWithCDCommand(stereo); StereoOffCommand stereoOffWithCD = new StereoOffCommand(stereo); LightOnCommand lightOn = new LightOnCommand(light); LightOffCommand lightOff = new LightOffCommand(light); TVOnCommand tvOn = new TVOnCommand(tv); TVOffCommand tvOff = new TVOffCommand(tv); // Set the slot position (which button of the remote control corresponds to which device switch) remoteControl.setCommand(0, lightOn, lightOff); remoteControl.setCommand(3, stereoOnWichCD, stereoOffWithCD); remoteControl.setCommand(5, tvOn, tvOff); // Output slot position System.out.println(remoteControl); // Press switch remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); remoteControl.onButtonWasPushed(3); remoteControl.offButtonWasPushed(3); remoteControl.onButtonWasPushed(5); remoteControl.offButtonWasPushed(5); } }
Design sketch
+1~~~~
In this example, I specifically reserved the revocation function. Let's see how the remote control with the revocation function (undo) works.
Create a new undoCommandTest class
package TestMain; import Control.RemoteControl; import Entity.Light; import Implements.LightOffCommand; import Implements.LightOnCommand; public class undoCommandTest { public static void main(String[] args) { // Instantiated remote controller RemoteControl remoteControl = new RemoteControl(); // Instances need to control objects and pass them into the house location Light light = new Light("A living room"); // Calling Device Switching Method LightOnCommand lightOn = new LightOnCommand(light); LightOffCommand lightOff = new LightOffCommand(light); // Set the slot position (which button of the remote control corresponds to which device switch) remoteControl.setCommand(0, lightOn, lightOff); // Press switch remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); // Output slot position System.out.println(remoteControl); // Revoke System.out.println("Press the Undo button"); remoteControl.undoButtonWasPushed(); System.out.println(""); remoteControl.offButtonWasPushed(0); remoteControl.onButtonWasPushed(0); System.out.println(remoteControl); System.out.println("Press the Undo button"); remoteControl.undoButtonWasPushed(); } }
Design sketch
It seems that the function of Undo is OK, and I even have the effect of Undo in Java Web, 23333.
Thank you for seeing here, the top part of command mode is over here. I write freely. If there are any shortcomings or mistakes, I hope to give directions. I will bend down at 90 degrees. Soon I will publish the content of command mode. I will live and program endlessly.
Reference Book: Head First Design Patterns