Design Pattern - Command(Java)
作者:互联网
分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net
Definition
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Participants
The classes and/or objects participating in this pattern are:
- Command (Command)
- Declares an interface for executing an operation
- ConcreteCommand (CalculatorCommand)
- Defines a binding between a Receiver object and an action
- Implements Execute by invoking the corresponding operation(s) on Receiver
- Client (CommandApp)
- Creates a ConcreteCommand object and sets its receiver
- Invoker (User)
- Asks the command to carry out the request
- Receiver (Calculator)
- Knows how to perform the operations associated with carrying out the request.
Sample Code in Java
This structural code demonstrates the Command pattern which stores requests as objects allowing clients to execute or playback the requests.
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.sample;
/**
* The 'Command' abstract class.
*
* @author Chimomo
*/
abstract class Command {
// The receiver.
protected final Receiver receiver;
/**
* Initializes a new instance of the "Command" class.
*
* @param receiver
*/
protected Command(Receiver receiver) {
this.receiver = receiver;
}
/**
* Execute.
*/
public abstract void execute();
}
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.sample;
/**
* The 'ConcreteCommand' class.
*
* @author Chimomo
*/
class ConcreteCommand extends Command {
/**
* Initializes a new instance of the "ConcreteCommand" class.
*
* @param receiver
*/
public ConcreteCommand(Receiver receiver) {
super(receiver);
}
/**
* Execute.
*/
@Override
public void execute() {
this.receiver.action();
}
}
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.sample;
/**
* The 'Invoker' class.
*
* @author Chimomo
*/
class Invoker {
// The command.
private Command command;
/**
* Execute command.
*/
public void executeCommand() {
this.command.execute();
}
/**
* Set command.
*
* @param command
*/
public void setCommand(Command command) {
this.command = command;
}
}
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.sample;
/**
* Startup class for Structural Command Design Pattern.
*
* @author Chimomo
*/
class Program {
/**
* Entry point into console application.
*
* @param args The arguments
*/
public static void main(String[] args) {
// Create receiver, command, and invoker.
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
// Set and execute command.
invoker.setCommand(command);
invoker.executeCommand();
}
}
/*
Output:
Called Receiver.action()
*/
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.sample;
/**
* The 'Receiver' class.
*
* @author Chimomo
*/
class Receiver {
/**
* The action.
*/
public void action() {
System.out.println("Called Receiver.action()");
}
}
This real-world code demonstrates the Command pattern used in a simple calculator with unlimited number of undo's and redo's.
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.realworld;
/**
* The 'Receiver' class.
*
* @author Chimomo
*/
class Calculator {
// The current value.
private int currentValue;
/**
* The operation.
*
* @param operand
*/
public void operation(char operator, int operand) {
switch (operator) {
case '+':
this.currentValue += operand;
break;
case '-':
this.currentValue -= operand;
break;
case '*':
this.currentValue *= operand;
break;
case '/':
this.currentValue /= operand;
break;
}
System.out.println(String.format("Current value = %3d (following %s %d)", this.currentValue, operator, operand));
}
}
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.realworld;
/**
* The 'ConcreteCommand' class.
*
* @author Chimomo
*/
class CalculatorCommand extends Command {
// The calculator.
private final Calculator calculator;
// The operator.
private char operator;
// The operand.
private int operand;
/**
* Initializes a new instance of the "CalculatorCommand" class.
*
* @param calculator
* @param operator
* @param operand
*/
public CalculatorCommand(Calculator calculator, char operator, int operand) {
this.calculator = calculator;
this.operator = operator;
this.operand = operand;
}
/**
* Execute.
*/
@Override
public void execute() {
this.calculator.operation(this.operator, this.operand);
}
/**
* Unexecute.
*/
@Override
public void unExecute() {
this.calculator.operation(this.undo(this.operator), this.operand);
}
/**
* undo.
*
* @return
*/
private char undo(char operator) {
switch (operator) {
case '+':
return '-';
case '-':
return '+';
case '*':
return '/';
case '/':
return '*';
default:
throw new IllegalArgumentException("operator: " + operator);
}
}
}
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.realworld;
/**
* The 'Command' abstract class.
*
* @author Chimomo
*/
abstract class Command {
/**
* Execute.
*/
public abstract void execute();
/**
* Unexecute.
*/
public abstract void unExecute();
}
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.realworld;
/**
* Startup class for Real-World Command Design Pattern.
*
* @author Chimomo
*/
class Program {
/**
* Entry point into console application.
*
* @param args The arguments
*/
public static void main(String[] args) {
// Create user and let her compute.
User user = new User();
// User presses calculator buttons.
user.compute('+', 100);
user.compute('-', 50);
user.compute('*', 10);
user.compute('/', 2);
// undo 4 commands.
user.undo(4);
// redo 3 commands.
user.redo(3);
}
}
/*
Output:
Current value = 100 (following + 100)
Current value = 50 (following - 50)
Current value = 500 (following * 10)
Current value = 250 (following / 2)
---- undo 4 levels
Current value = 500 (following * 2)
Current value = 50 (following / 10)
Current value = 100 (following + 50)
Current value = 0 (following - 100)
---- redo 3 levels
Current value = 100 (following + 100)
Current value = 50 (following - 50)
Current value = 500 (following * 10)
*/
/*
* Chimomo's Blog: https://blog.csdn.net/chimomo/
*/
package chimomo.learning.java.designpattern.command.realworld;
import java.util.ArrayList;
import java.util.List;
/**
* The 'Invoker' class.
*
* @author Chimomo
*/
class User {
// The calculator.
private final Calculator calculator = new Calculator();
// The commands.
private final List<Command> commands = new ArrayList<>();
// The current command.
private int currentCommand;
public void compute(char operator, int operand) {
// Create command operation and execute it.
Command command = new CalculatorCommand(this.calculator, operator, operand);
command.execute();
// Add command to undo list.
this.commands.add(command);
this.currentCommand++;
}
/**
* Redo.
*
* @param levels
*/
public void redo(int levels) {
System.out.println(String.format("---- redo %d levels ", levels));
// Perform redo operations.
for (int i = 0; i < levels; i++) {
if (this.currentCommand < this.commands.size() - 1) {
Command command = this.commands.get(this.currentCommand++);
command.execute();
}
}
}
/**
* Undo.
*
* @param levels
*/
public void undo(int levels) {
System.out.println(String.format("---- undo %d levels ", levels));
// Perform undo operations
for (int i = 0; i < levels; i++) {
if (this.currentCommand > 0) {
Command command = this.commands.get(--this.currentCommand);
command.unExecute();
}
}
}
}
标签:Java,Chimomo,Pattern,Command,operator,command,class,chimomo 来源: https://blog.csdn.net/chimomo/article/details/81014930