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来处理