设计模式之 Command - 命令模式Command(CoR)模式也叫命令模式,是由GoF提出的23种软件设计模式的一种。本文
设计模式之 Command - 命令模式
Command(CoR)模式也叫命令模式,是由GoF提出的23种软件设计模式的一种。本文介绍设计模式中的(Command)模式的概念,用法,并用Command模式给出了一个简单的execute/undo实现。
Command????Command抽象类。
ConcreteCommand????Command的具体实现类。
Receiver????需要被调用的目标对象。
Invorker????通过Invorker执行Command对象。
Client????调用方。
Command模式的应用范例下面,我们使用Command模式实现一个简单的execute/undo操作。
在该范例中,我们有一个简单的操作:对字符串做append操作,这个操作由Receiver类实现;另外,我们需要记录操作历史,并能简单加以回退(undo),所以我们采用Command模式实现。
文件一览:
Client????测试类
Command????Command抽象类
UndoableCommand????支持undo操作的Command抽象类,该类是Command类的子类
ConcreteCommand????具体的UndoableCommand实现类,该类继承UndoableCommand类,所以支持undo操作
CommandManager????Command管理类。该类使用Stack来管理执行过的Command对象,并提供executeCommand()与undoCommand()方法
Receiver????执行任务的目标类
Invoker????这个类在我们的例里没有被用到,但我们仍给出了它的一个参考实现,不过用注释表示它不可用
代码:
import java.util.Stack;
public class Client {
????/**
???? * Test Command Pattern
???? *
???? */
????public static void main(String[] args) {
????????CommandManager commandMgr = new CommandManager();
????????
????????Receiver receiver = new Receiver();
????????System.out.println("--- execute command ---");
????????Command commandAaa = new ConcreteCommand(receiver, "aaa");
????????commandMgr.executeCommand(commandAaa);
????????
????????Command commandBbb = new ConcreteCommand(receiver, "bbb");
????????commandMgr.executeCommand(commandBbb);
????????
????????Command commandCcc = new ConcreteCommand(receiver, "ccc");
????????commandMgr.executeCommand(commandCcc);
????????
????????Command commandDdd = new ConcreteCommand(receiver, "ddd");
????????commandMgr.executeCommand(commandDdd);
????????
????????System.out.println(receiver.getData());
????????
????????System.out.println("-- undo ---");
????????commandMgr.undoCommand();
????????commandMgr.undoCommand();
????????System.out.println(receiver.getData());
????}
}
/**
* Command
* abstract command class
*
*/
abstract class Command {
????protected Receiver receiver;
????protected String param;
????public Command(Receiver receiver, String expr) {
????????this.receiver = receiver;
????????this.param = expr;
????}
????abstract public void execute();
}
/**
* UndoableCommand
* abstract undo supportable command class which extends from Command class
*
*/
abstract class UndoableCommand extends Command {
????public UndoableCommand(Receiver receiver, String expr) {
????????super(receiver, expr);
????}
????abstract public void undo();
}
/**
* ConcreteCommand
* concrete command class which extends from UndoableCommand
*
*/
class ConcreteCommand extends UndoableCommand {
????private String previousData = null;
????public ConcreteCommand(Receiver receiver, String expr) {
????????super(receiver, expr);
????}
????@Override
????public void execute() {
????????previousData = receiver.getData();
????????receiver.append(this.param);
????}
????@Override
????public void undo() {
????????receiver.setData(previousData);
????}
}
/**
* CommandManager
* Command Manager class which stack the exe
*
*/
class CommandManager {
????private Stack commandStack = new Stack();
????public void executeCommand(Command cmd) {
????????cmd.execute();
????????if (cmd instanceof UndoableCommand) {
????????????commandStack.push(cmd);
????????}
????}
????public void undoCommand() {
????????if (commandStack.size() > 0) {
????????????UndoableCommand cmd = (UndoableCommand) commandStack.pop();
????????????cmd.undo();
????????} else {
????????????throw new UnsupportedOperationException("");
????????}
????}
}
/**
* Receiver
* target object
*
*/
class Receiver {
????private String data = "";
????public void append(String expr) {
????????data += expr;
????}
????public String getData() {
????????return data;
????}
????public void setData(String data) {
????????this.data = data;
????}
}
/**
class Invoker {
????private Command command;
????public void setCommand(Command command) {
????????this.command = command;
????}
????public void executeCommand() {
????????command.execute();
????}
}
*/
执行Client,输出结果:
C:\Command>javac *.java
C:\Command>java Client
--- execute command ---
aaabbbcccddd
-- undo ---
aaabbb
C:\Command>
我们可以看到,使用Command模式非常简单地就实现了undo操作。