0 命令模式和责任链模式
命令模式和责任链模式是两种完全相反的模式。
命令模式是需要将请求排队处理。因此将请求封装成对象放入队列。
而责任链模式则是,可能同一对象需要多个函数只有一个函数能处理。或是多个函数都需要处理。
1 命令模式
1.0 需求
高并发情况下,将延迟并发执行的命令,于是将所提交的命令封装成对象存储在一个队列中,然后一个处理者顺序执行。
将请求封装为对象,也就是说要处理的资源处理的命令封装成对象。然后一个Command作为基类。
每种命令使用一个类封装,都继承Command。
然后一个处理的对象Process,有add的接口,将Command保存,一个do接口,开始执行所有的命令。
1.1 实现
当然为了效率,是可以传指针的,但是需要是智能指针,因为,多线程的问题。
// 封装命令实际类 class SubStr { public: Substr(string str):str(str){} void sub(); private: string str; }; // 封装命令实际类 class CatStr { public: Catstr(string str):str(str){} void Cat(); private: string str; }; // 为了实现多态的基类 class ABCommand { public: virtual void do() =0 ; }; // 提供同一接口的类 class SubCommand :public ABCommand { public: SubCommand(SubStr obj):obj(obj){} void do(){obj->sub();} private: SubStr obj; }; // 另一个,省略了 //接受者,具体的执行者 class Process { public: void add(); void do(); private: vector<Command> list; }
1.2 扩展
消息队列也是将请求封装成对象,然后依次处理。
2 责任链模式
2.0 需求
当一个对象的处理过程需要经过多级的时候,也就是说,一个对象可能被不同的命令处理。
那么就需要责任链模式。
2.1 实现
责任链模式的实现,是这样的:
将处理请求的函数,封装为一个类。类继承自同一个基类。类中还有一个基类的指针用于保存下一级处理的类。
而处理请的函数应该判断是否能够处理该请求,如果不能处理,就向下一级转发。
//处理类的基类 class AbHandler { public: virtual bool exc(Req * req)=0; private: AbHandler *_next; //这个用于保存责任链的下一个 }; //处理类,根据信息判断是否可以执行。 class Exc1Handler:AbHandler { public: Exc1Handler(AbHandler* handler):_next(handler); virtual bool exc(Req * req) { if(/*判断req信息和本类的其他数据成员是否能够处理该请求*/) { //do return true; } return _next->exc(req); } }; //链的终端,确保一定可以执行。 class EndHandler:Abhandler { //其他不变,构造函数传入参数为空 public: virtual bool exc() { //提示信息 return false; } }; int main() { EndHandler *endHandler=new EndHandler; Exc1Handler *exc1=new Exc1Handler(endHandler); //.....添加其他的。 Exc9Handler *exc9=new Exc9Handler(exc8); //另外一个请求类。。。 Req req; exc9->exc(req); }
2.2 缺点
从上面的代码可以看出:责任链的创建过程还是比较复杂的。因为需要一级级的创建。
因此可以更改为使用vector封装函数对象,然后处理的时候使用for来处理