本文深入浅出的讲述了设计模式中的命令模式 , 并给出了简单的示例 , 例子浅显易懂 , 并附带源代码。 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

      命令模式属于行为模式。意图是将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求的排队或记录请求的日志,以及支持可以撤销的操作。又叫动作 (Action) 或者事务 (Transaction)

      有时必须向一个对象提交请求,但是并不知道关于被请求的操作或者请求的接受者的任何信息。命令模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求,这个对象可以被存储并像其他的对象一样被传递,这一个模式的关键是抽象的 Command 类,它定义了一个执行操作的接口,其最简单的形式是一个抽象的 Execute 操作,具体的 Command 子类将接收者作为其一个实例变量,并实现 Execute 操作 , 制定接收者采取的动作,而接收者有执行该请求所需的具体信息。

适用性:

l         抽象出待执行的动作以参数化某对象,适用过程语言中的回调函数表达这种参数化的机制。所谓的回调函数指函数先在某处注册,而他将在稍后的某个需要的时候被调用。 Command 模式是回调机制的一个面向对象的替代品。

l         在不同的时刻指定、排列和执行的请求。

l         支持取消操作

l         支持修改日志,这样当系统崩溃时这些修改可以被从新作一遍。

l         用构建在原语操作上的高层操作构造一个系统。这样一种结构支持事务的信息系统中很常见。

参与者:

      Command :声明执行操作的借口。

      ConcreteCommand: 将一个接收者对象邦定于一个动作。

           调用者收者相应的操作,以实现 Execute

      Invoker(Dealer): 要求该命令执行这个请求。

      Receiver(fan ,light) :知道如何实施与执行一个请求相关的操作,任何类都可能是一个接收者。
                                图1
在这个例子中,被操作的对象有电风扇(fan)和灯(light),他们主要有开和关两种动作。把操作开或者关的请求封装成一个对象,于是就有了在本例中就有FanOn(Off)CommandlightOnOffCommand四个类,每个类都实现了Command接口,具备执行和撤销操作。
这些对象的协作关系是 Client创建一个具体的命令对象(fanOnCommand 并指定他的Receiverfan)对象,Invoker(dealer)对象存储该具体的命令对象,该Invoker通过调用Command对象的Execute对象的Execute操作来提交一个请求,若该命令是可撤销的,具体的命令对象就再执行Execute之前存储当前的状态以取消该命令。具体对象调用它的Receiver对象的一些操作以执行该请求。
Command的代码:
       package command;

public interface Command{

    public void execute();

    public void unExecute();

}

Fan 的代码

package command;

public class Fan{

    private String state ;

    public Fan(){

       state = "off" ;

    }

    public void startRotate(){

       System. out .println( "Fan is Being started !" );

       state = "on" ;

    }

    public void stopRotate(){

       System. out .println( "Fan has been stopped!" );

       state = "off" ;

    }

    public String getState(){

       return state ;

    }

}

 

FanOnCommand代码:

package command;

public class FanOnCommand implements Command{

    private Fan fan ;

    private boolean change ;

    public FanOnCommand(Fan f){

       change = false ;

       fan = f;

    }

    public void execute(){

       if ( "off" .equals( fan .getState())){

           change = true ;

           fan .startRotate();

       }

       else {

           change = false ;

           System. out .println( "The fan has been started! No Action!" );

       }

    }

    public void unExecute(){

       if ( change ){

           fan .stopRotate();

           System. out .println( " ==>from undo command!" );

       }

       else {

           System. out .println( "The Fan has been started! Undo nothing!" );

       }

    }

}

Dealer代码:

package command;

import java.util.Vector;

public class Dealer{

    private Vector v ;

    public Dealer(){

       v = new Vector();

    }

    public void deal(Command command){

       v .addElement(command);

       command.execute();

    }

    public boolean unDeal(){

       if ( v .size()>0){

           Command command =(Command) v .get( v .size()-1);

           command.unExecute();

           v .remove( v .size()-1);

           return true ;

       }

       else {

           return false ;

       }

    }

}

Dealer 的代码:

package command;

public class Client{

    public static void main(String[] args){

       Fan fan = new Fan();

       Light light = new Light();

       Dealer dealer = new Dealer();

       Command command = new LightOnCommand(light);

       dealer.deal(command);

       command = new FanOnCommand(fan);

       dealer.deal(command);

      

       command = new LightOnCommand(light);

       dealer.deal(command);

       command = new FanOnCommand(fan);

       dealer.deal(command);

 

       command = new LightOffCommand(light);

       dealer.deal(command);

      

       command = new FanOffCommand(fan);

       dealer.deal(command);

 

       while (dealer.unDeal());

    }

}

总结:命令模式有效的解决了操作中的撤销和重做动作的实现问题。桌面应用系统中的撤销和重做操作的实现是提高系统应用可信度的重要标志之一。