博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式——命令模式(Command)

Posted on 2008-09-02 12:25  Anna Yang  阅读(314)  评论(0编辑  收藏  举报
设计模式(15):命令模式(Command)
 
命令模式(Command)
定义
   将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化; 对请求排队或记录请求日志,以及支持可撤销的操作
概述
    在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合,这就是本文要说的Command模式。
 
命令模式(Command)结构图
command类,用来声明执行操作的接口 
abstract class Command
{
    
protected Receiver receiver;
    
public void Execute()
    {
        
public Command(Receiver receiver)
        {
            
this.receiver=receiver;
        }
        
abstract public void Execute();
    }
}
 
ConcreteCommand类将一个接受者对象邦定于一个动作,调用接受者相应的操作,以实现Execute; 
class ConcreteCommand:Command
{
    
public ConcreteCommand(Receiver receiver):base(receiver)
    {}
    
public override void Execute()
    {
        receiver.Action();
    }
}
 
Invoker类,要求该命令执行这个请求 
class Invoker
{
    
private Command command;
    
public SetCommand(Command command)
    {
        
this.command=command;
    }
    
    
public void ExecuteCommand()
    {
        command.Execute();
    }
}
 
Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接受者 
class Receiver
{
    
public void Action()
    {
        Console.WriteLine(
"执行请求!");    
    }
}
 
客户端代码,创建一个具体命令对象并设定它的接受者 
static void Main()
{
    Receiver r
=new Receiver();
    Command c
=new ConcreteCommand(r);
    Invoker i
=new Invokr();
    i.SetCommand(c);
    i.ExecuteCommand();
    
    Console.Read();
}
 
作用
1.它能较容易的设计一个命令队列;
2.在需要的情况下,可以较容易地将命令记入日志。
3.允许接受请求的一方决定是否要否决请求。
4.可以容易地实现对请求的撤销和重做。
5.由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
6.命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
 
注意:不要为代码添加基于猜测的,实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要急着去实现它,事实上在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。