Command模式是什么?
Command将一个请求封装为一个对象,从而使得可以用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
Command模式中,有几个关键角色:
1. Command,声明执行操作的接口
2. ConcreteCommand把一个接受者对象绑定于一个动作,调用接收者相应的操作,实现Execute
3. Invoker要求该命令执行这个请求
4. Receiver知道如何执行一个请求相关的操作。
Command模式的例子
下面我们用文档编辑中的Redo(再次操作)和Undo(撤销操作)来说明Command模式。
//base command command角色
abstract class Command
{
abstract public void Redo();
abstract public void Undo();
}
//concrete implementation ConcreteCommand角色
class DocumentEditCommand : Command
{
private Document _editableDoc;
private string _text;
public DocumentEditCommand(Document doc, string text)
{
_editableDoc = doc;
_text = text;
_editableDoc.Write(_text);
}<pre name="code" class="csharp"> override public void Redo()
{
_editableDoc.Write(_text);
}
override public void Undo()
{
_editableDoc.Erase(_text);
}
}
//invoker 角色
class DocumentInvoker
{
private ArrayList _commands = new ArrayList();<pre name="code" class="csharp"> private Document _doc = new Document();
<pre name="code" class="csharp"> public void Redo( int level )
{
Console.WriteLine( "---- Redo {0} level ", level );
((Command)_commands[ level ]).Redo();
}
public void Undo( int level )
{
Console.WriteLine( "---- Undo {0} level ", level );
((Command)_commands[ level ]).Undo();
}
public void Write(string text)
{
DocumentEditCommand cmd = new
DocumentEditCommand(_doc,text);
_commands.Add(cmd);
}
public string Read()
{
return _doc.ReadDocument();
}
}
import java.util.List;
import java.util.ArrayList;
/** The Command interface */
public interface Command {
void execute();
}
/** The Invoker class */
public class Switch {
private List<Command> history = new ArrayList<Command>();
public void storeAndExecute(Command cmd) {
this.history.add(cmd); // optional
cmd.execute();
}
}
/** The Receiver class */
public class Light {
public void turnOn() {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
/** The Command for turning on the light - ConcreteCommand #1 开灯命令*/
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight = light;
}
@Override // Command
public void execute() {
theLight.turnOn();
}
}
/** The Command for turning off the light - ConcreteCommand #2 关灯命令*/
public class FlipDownCommand implements Command {
private Light theLight;
public FlipDownCommand(Light light) {
this.theLight = light;
}
@Override // Command
public void execute() {
theLight.turnOff();
}
}
/* The test class or client */
public class PressSwitch {
public static void main(String[] args){
Light lamp = new Light();
Command switchUp = new FlipUpCommand(lamp);
Command switchDown = new FlipDownCommand(lamp);
Switch mySwitch = new Switch();
switch(args[0]) {
case "ON":
mySwitch.storeAndExecute(switchUp);
break;
case "OFF":
mySwitch.storeAndExecute(switchDown);
break;
default:
System.out.println("Argument \"ON\" or \"OFF\" is required.");
}
}
}
注意:Command模式中,用了一个List<command>来记录Command的执行历史,Command的实际执行是由receiver来做的。