命令模式

特征

该模式的特征在于将请求封装为对象,从而将行为请求者与行为施行者解耦出来。

目的

行为请求和施行分离开,进行类似事务处理,可还原、重做、重现请求。

详情

假设现有五指棋玩家Actor:

class Actor
{
    void play(int pos_x,int pos_y);
    void undo();
}

该玩家有两种行为,下棋和悔棋。通常的操作是对于外界(比如键盘)的输入,玩家做出不同反应,即执行对应的成员方法。

void update(int cmd,Actor *player)
{
    if(cmd== 0)
    {
        player->play(...);
    }
    else if(cmd == 1)
    {
        player->undo();
    }
}

现在玩家在键盘按下数字键1进行悔棋,请问该如何操作?

当然undo方法也可以设置参数,即传入上一次落子的坐标,可达到效果,因此我们可以记录每次落子的坐标。

但这里的例子是五指棋,对于悔棋我们只可以进行一次(两次意味着把对手的也回退了),如果是对于可以连续回退的情景呢?

分析上面的例子,落子和悔棋的行为与玩家紧密相连,是不是可以考虑将行为和执行者分离开呢?对于外界的指令我们就只关注指令本身,将其单独提取出来。

 指令输入-------->玩家执行

变为:

指令输入-------->指令对象-------->玩家执行

也就是:为每一条指令生成一个对象。

这样的好处是我们可以将随指令传入的参数一起打包,然后将该对象放置于等待队列就行,请求者的任务到这里已经完成。

接下来只需在不断的从等待队列提取指令对象并执行就可以,这属于执行者的工作。

如此一来,请求者和执行者的工作被分离开来,请求者不用等待执行者执行完动作返回TRUE后才能继续下一步,而且指令放在队列中,可被延时执行,这是很有意义的一种思想(例如大量用户同一时刻登录某服务器,这时候就需要排队,将登录请求打包放进等到队列,等待服务器去调度就行)。

简单例子

class Actor
{
    void run();
    void crouch();
    void fire();
}
class Command
{
    virtual void excute() = 0;
    Actor *actor;
}

class RunCommand:public Command
{
    void excute() {actor -> run();}
}

class CrouchCommand:public Command
{
    void excute(){actor -> crouch();}
}

class FireCommand:public Command
{
    void excute(){actor -> fire();}
}
class Scene()
{
    void doSomething(int arg);
    void update();

    Actor* actor;
    std::stack<Command> commandList;
}

void Scene::doSomething(int arg)
{
    if(arg == 0)
    {
        RunCommand command(actor);
        commandList.push(command);
    }
    else if(arg == 1)
    {
        CrouchCommand command(actor);
        commandList.push(command);
    }
    else
    {
        FireCommand command(actor);
        commandList.push(command);
    }
}

void Scene::update()
{
    while(!commandList.empty())
    {
        auto commander = commandList.pop();
        commander.excute();
    }
}

例子是随意写的,目的只是为了表达想法,不要在意有没有语法错误等等。

它的类图就不画了,直接看下菜鸟教程的图:

这里的ICommand和子类ConcreteCommand就是指令类。

Receiver是具体执行行为的类,对应于例子的Actor。

Invoker对应与上面的Scene类,相当于管理指令和执行者的管理器吧。

Client就当作一个大环境吧,也可以理解为一个管理器。

总结

可能我的理解不到位,欢迎大佬批评指正。

参考:菜鸟教程-命令模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值