灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:2577回复:0

[C++技术]设计模式C++描述----19.命令(Command)模式

楼主#
更多 发布于:2012-09-06 11:35

一. 举例说明

我们知道,在多线程程序中,多个用户都给系统发 Read 和 Write 命令。这里有几点需要说明:
1. 首先明确一点,所有的这些 Read 和 Write 命令都是调用一个库函数。

2. 用户并不需要知道别的用户的存在,也不管别人发不发命令,只管自己发命令,最后给结果即可。

3. 这些命令先是到了一个消息队列里面,然后由消息队列调用库函数。

结构图如下:


代码如下:
[cpp] class Command;

//实施与执行类  
class Reciever  
{  
public:  
    void Action()
    {
        cout<<"Do action !!"<<endl;
    }
};

//抽象命令类  
class Command  
{  
public:  
    virtual ~Command() {}

    virtual void Excute() = 0;

protected:  
    Command() {}
};

//Read 命令  
class Read_Command:public Command  
{  
public:  
    Read_Command(Reciever* rev)
    {
        this->_rev = rev;
    }

    ~Read_Command()
    {
        delete this->_rev;
    }

    void Excute()
    {
        cout<<"Read Command..."<<endl;  
        _rev->Action();
    }

private:  
    Reciever* _rev;  
};

//Write 命令  
class Write_Command:public Command  
{  
public:  
    Write_Command(Reciever* rev)
    {
        this->_rev = rev;
    }
    
    ~Write_Command()
    {
        delete this->_rev;
    }
    
    void Excute()
    {
        cout<<"Write_Command..."<<endl;  
        _rev->Action();
    }
    
private:  
    Reciever* _rev;  
};

//要求命令执行的类  
class Invoker
{  
public:  
    Invoker(Command* cmd)
    {
        _cmd = cmd;
    }

    Invoker()
    {
    }

    ~Invoker()
    {
        delete _cmd;
    }

    //通知执行类执行  
    void Notify()
    {
        list<Command*>::iterator it = cmdList.begin();
        
        for (it; it != cmdList.end(); ++it)
        {
            _cmd = *it;
          _cmd->Excute();
        }
    }

    //添加命令  
    void AddCmd(Command* pcmd)
    {
        cmdList.push_back(pcmd);
    }
    
    //删除命令  
    void DelCmd(Command* pcmd)
    {
        cmdList.remove(pcmd);
    }

private:  
    Command* _cmd;  

    list<Command*> cmdList;
};


//测试代码 www.atcpu.com  
int main(int argc,char* argv[])  
{  
    Reciever* rev = new Reciever(); //定义一个执行类  
    
    Command* cmd1 = new Read_Command(rev);//Read 命令  
    Command* cmd2 = new Write_Command(rev);//Write 命令  

    Invoker inv; //管理所有命令  
    
    inv.AddCmd(cmd1);
    inv.AddCmd(cmd2);
    inv.Notify(); //通知执行类,执行  

    inv.DelCmd(cmd1);
    inv.Notify();

    return 0;  
}
class Command;
//实施与执行类
class Reciever
{
public:
void Action()
{
  cout<<"Do action !!"<<endl;
}
};
//抽象命令类
class Command
{
public:
virtual ~Command() {}
virtual void Excute() = 0;
protected:
Command() {}
};
//Read 命令
class Read_Command:public Command
{
public:
Read_Command(Reciever* rev)
{
  this->_rev = rev;
}
~Read_Command()
{
  delete this->_rev;
}
void Excute()
{
  cout<<"Read Command..."<<endl;
  _rev->Action();
}
private:
Reciever* _rev;
};
//Write 命令
class Write_Command:public Command
{
public:
Write_Command(Reciever* rev)
{
  this->_rev = rev;
}

~Write_Command()
{
  delete this->_rev;
}

void Excute()
{
  cout<<"Write_Command..."<<endl;
  _rev->Action();
}

private:
Reciever* _rev;
};
//要求命令执行的类
class Invoker
{
public:
Invoker(Command* cmd)
{
  _cmd = cmd;
}
Invoker()
{
}
~Invoker()
{
  delete _cmd;
}
//通知执行类执行
void Notify()
{
  list<Command*>::iterator it = cmdList.begin();
  
  for (it; it != cmdList.end(); ++it)
  {
   _cmd = *it;
    _cmd->Excute();
  }
}
//添加命令
void AddCmd(Command* pcmd)
{
  cmdList.push_back(pcmd);
}

//删除命令
void DelCmd(Command* pcmd)
{
  cmdList.remove(pcmd);
}
private:
Command* _cmd;
list<Command*> cmdList;
};

//测试代码
int main(int argc,char* argv[])
{
Reciever* rev = new Reciever(); //定义一个执行类

Command* cmd1 = new Read_Command(rev);//Read 命令
Command* cmd2 = new Write_Command(rev);//Write 命令
Invoker inv; //管理所有命令

inv.AddCmd(cmd1);
inv.AddCmd(cmd2);
inv.Notify(); //通知执行类,执行
inv.DelCmd(cmd1);
inv.Notify();
return 0;
}
二. 命令模式

定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户时行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。



优点:
1. 它能比较容易地设计一个命令队列。
2. 在需要的情况下,可以较容易地将命令记入日志。
3. 允许接收请求的一方决定是否要否决请求。
4. 可以容易地实现对请求的撤销和重做。
5. 增加新的具体命令类很容易
6. 把请求一个操作的对象(Command)与知道怎么执行一个操作的对象(Receiver)分割开来。


作者 lwbeyond


喜欢0 评分0
游客

返回顶部