前言
本周五参加了Command(命令 )模式研讨会,本文的目的是对这个模式的总结和分享,希望对需要学习这个设计模式的同学有所帮助。本文一共分为两个部分,第一个部分是命令模式的基础知识总结;第二个部分是分享命令模式简单示例。AWTK-MVVM 是一套为 AWTK 用 C 语言开发,并支持各种脚本语言的 MVVM 框架,实现了数据绑定、命令绑定和窗口导航等基本功能,使用 AWTK-MVVM 开发应用程序,无需学习 AWTK 本身的 API,只需学习绑定规则和 Model 的实现方式即可
一、命令模式总结
1、模式意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。2、参与者
Command
– 声明执行操作的接口;
ConcreteCommand
– 将一个接收者对象绑定于一个动作;
– 调用接收者相应的操作,以实现execute;
Client
– 创建具体命令对象并设定它的接收者;
Invoker
– 要求该命令执行这个请求;
Receiver
– 知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者;
3、结构、协作、适用性及效果
结构图:
协作:
1、client创建一个concreteCommand对象并指定它的receiver对象;
2、invoker对象存储该concreteCommand对象;
3、该invoker通过调用command对象的execute操作提交一个请求。若该命令是可撤销的,
concreteCommand就在执行execute操作前存储当前状态以用于取消该命令。
4、concreteCommand对象调用它的receiver的一些操作以执行该请求。
1、抽象出待执行的动作以参数化某个对象(回调函数)。
2、在不同时刻指定、排列和执行请求。
3、支持取消操作。
4、支持修改日志,这样当系统崩溃时,这些修改可以被重做一次。
5、用构建在原语操作上的高层操作构建一个系统。
效果:
1、Command模式将调用操作的对象与知道如何实现该操作的对象解耦。
2、command是头等的对象。
3、可将多个命令装配成一个组合命令。
4、增加新的命令很容易,无须改变现有的类。
二、命令模式简单示例
1、用例描述
在客服系统中,我们一般 会对客户进行等级划分,普通用户由普通客服提供服务,高等级的VIP用户由vip专用客户服务通道提供服务。普通用户只能使用普通客服通道,VIP用户也只提供VIP专用服务通道。当它们请求服务时,会直接由相应的客服提供各自的服务。高级客服在VIP通道提供服务,普通客服在普通客服通道提供服务。2、示例代码
//客服
class Servicer {
public:
Servicer(int level);
void do_service();
private:
int level;
};
//服务命令接口
class Service {
public:
Service(Servicer* servicer);
virtual ~Service();
virtual void execute() = 0;
protected:
Servicer* get_servicer();
private:
Servicer* m_servicer;
};
//普通服务
class CommonService : public Service {
public:
CommonService(Servicer* servicer);
virtual void execute();
};
void CommonService::execute() {
get_servicer()->do_service();
}
//vip服务
class VipService : public Service {
public:
VipService(Servicer* servicer);
virtual void execute();
};
void VipService::execute() {
get_servicer()->do_service();
}
// 客户代码
....
Servicer common_user(0);
Servicer vip_user(1);
// 绑定客服到服务通道
CommonService* common_service = new CommonService(&common_user);
VipService* vip_service = new VipService(&vip_user);
//设置普通用户服务
set_common_service(common_service);
//设置vip用户服务
set_vip_service(vip_service);
....
//普通用户请求服务
on_common_service();
//vip用户请求服务
on_vip_service();
....