命令(Command)模式属于对象的行为模式【GOF95】。命令模式又称为行动(Action)模式或交易(Transaction)模式。命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
命令模式的结构
命令模式的类图如下:
命令模式涉及到五个角色,它们分别是:
- 客户(Client)角色:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。
- 命令(Command)角色:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色。
- 具体命令(ConcreteCommand)角色:定义一个接受者和行为之间的弱耦合;实现Execute()方法,负责调用接收考的相应操作。Execute()方法通常叫做执方法。
- 请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
- 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
上面的叙述不是很好理解,应用程序的菜单或者目前手机上的图标panel的实现,都可以采用这个设计模式,最为典型的是undo和redo命令
public class Client {
public static void main(String[] args) {
CommandHistoryManager chm = new CommandHistoryManager();
for (int i = 0; i < 100; i++) {
CutCommand cutCmd = new CutCommand();
cutCmd.setSomeText(">>" + i);
DelCommand delCmd = new DelCommand();
delCmd.setSomeText("<<"+i);
chm.storeCommand(cutCmd);
chm.storeCommand(delCmd);
}
for(int i=0;i<200;i++){
chm.undo();
}
for(int i=0;i<200;i++){
chm.redo();
}
}
}
package behaviour.command;
import java.util.Vector;
public class CommandHistoryManager implements ICommandManager {
Vector<ICommand> undoList = new Vector<ICommand>();
Vector<ICommand> redoList = new Vector<ICommand>();
public void storeCommand(ICommand cmd) {
undoList.add(cmd);
}
public void clearAllCommand() {
undoList.removeAllElements();
redoList.removeAllElements();
}
public void undo() {
if (undoList.size() < 1)
return;
ICommand cmd = undoList.get(undoList.size() - 1);
cmd.undo();
undoList.remove(cmd);
redoList.add(cmd);
}
public void redo() {
if (redoList.size() < 1)
return;
ICommand cmd = redoList.get(redoList.size() - 1);
cmd.execute();
redoList.remove(cmd);
undoList.add(cmd);
}
}
package behaviour.command;
public class CutCommand implements ICommand {
private String someText ;
public void execute() {
System.out.println("cut some text:"+someText);
}
public void undo() {
System.out.println("undo cut some text:"+someText);
}
public String getSomeText() {
return someText;
}
public void setSomeText(String someText) {
this.someText = someText;
}
}
package behaviour.command;
public interface ICommand {
public void execute();
public void undo();
}
package behaviour.command;
public class DelCommand implements ICommand {
private String someText;
public void execute() {
System.out.println("delete some text:"+someText);
}
public void undo() {
System.out.println("undo del some text:"+someText);
}
public String getSomeText() {
return someText;
}
public void setSomeText(String someText) {
this.someText = someText;
}
}
package behaviour.command;
public interface ICommandManager {
public void storeCommand(ICommand cmd);
public void clearAllCommand();
public void undo();
public void redo();
}