本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:http://blog.youkuaiyun.com/lovelion/article/details/17517213
主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.职责链模式
以前大学和舍友玩锄大地,里面就已经蕴含着职责链模式。比我打一张牌,那么按照逆时针顺序,下家根据自身的牌决定打不打,直到最后。这个过程其实就已经形成类似的职责链模式。职责链可以是一条直线、一个环、或者一个树形结构。常见的是直线型,沿着一条单向的链式来传递请求。链上的每一个对象都是处理者,客户端只需把请求发送到链上即可,实现请求发送者和请求处理者解耦。
(1)定义
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
1)职责链模式结构图
2)参与者
a) Handler(抽象处理者):定义一个请求处理接口,实现后继链;也可以在这里定义一个抽象处理者对象,作为后继。
b) ConcreteHandler(具体处理者):处理它所负责的请求;可访问他的后继者,如果可以处理该请求,就处理之,否则将该请求转发给他的后继者。即一处理请求;二转发请求。
c) Client:向链上的处理者提交请求。
3)看图写代码
/*
** FileName : ChainPattern
** Author : lin005
** Date : 2015/01/30
** Description : More information, please go to http://blog.youkuaiyun.com/amd123456789
*/
#include<iostream>
using namespace std;
#define SAFE_DELETE(p) if(p){delete p; p = NULL;}
//购买Iphone6的请求
class buyIphoneRequest
{
public:
buyIphoneRequest(int m):money(m){}
int getMoney(){return money;}
private:
int money;
};
//抽象处理类
class Handler
{
public:
virtual void handleRequest(buyIphoneRequest* myRequest) = 0;
};
//洪总审批,5000元以下可以审批
class HongzongHandler:public Handler
{
public:
HongzongHandler(Handler* nh):NextHandler(nh){}
virtual void handleRequest(buyIphoneRequest* myRequest)
{
//超过5000元转发给弟总处理
if(myRequest->getMoney() > 5000)
{
cout<<"洪总转发给下个领导处理"<<endl;
NextHandler->handleRequest(myRequest);
}
else
{
cout<<"洪总直接处理了"<<endl;
}
}
private:
Handler* NextHandler; //下一个处理者
};
//弟总审批,5000~10000的额度可以审批
class DizongHandler:public Handler
{
public:
DizongHandler(Handler* nh):NextHandler(nh){}
virtual void handleRequest(buyIphoneRequest* myRequest)
{
int money = myRequest->getMoney();
if(money >5000 && money <= 10000)
{
cout<<"弟总处理了"<<endl;
}
//超过10000元转发给冰总处理
if(money > 10000)
{
cout<<"弟总转发给冰总处理"<<endl;
NextHandler->handleRequest(myRequest);
}
}
private:
Handler* NextHandler;
};
//冰总审批,只要超过10000元他都通过
class BingzongHandler:public Handler
{
public:
BingzongHandler(Handler* nh):NextHandler(nh){}
virtual void handleRequest(buyIphoneRequest* myRequest)
{
cout<<"冰总看都不看,直接批了!"<<endl;
}
private:
Handler* NextHandler;
};
//客户端
int main()
{
//客户端建立职责链
BingzongHandler* bing = new BingzongHandler(NULL);//冰总
DizongHandler* di = new DizongHandler(bing);//弟总
HongzongHandler* hong = new HongzongHandler(di);//洪总
//提出请求
buyIphoneRequest* bir1 = new buyIphoneRequest(5100);
buyIphoneRequest* bir2 = new buyIphoneRequest(12000);
//申请购买
hong->handleRequest(bir1);
hong->handleRequest(bir2);
SAFE_DELETE(bir1);
SAFE_DELETE(bir2);
SAFE_DELETE(bing);
SAFE_DELETE(hong);
SAFE_DELETE(di);
return 0;
}
4)注意
职责链模式并不是创建职责链,职责链的工作必须由系统的其他部分来完成,一般是在使用该职责链的客户端中创建职责链。
(2)总结
1)优点
a) 降低耦合度;该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅知道该请求会被正确的处理;接受者和发送者都没有对方的明确信息,且链中不需要知道链的结构。
b) 增强了给对象指派职责的灵活性;可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的职责。
c) 增加或删减一个具体处理者时,仅需在客户端重新建链即可,无需修改其他代码,算是符合开闭原则。
2)缺点
a) 不保证被接受处,没有明确的接受者,有可能最后都得不到处理;
b) 建链不当,有可能会造成循环调用,陷入死循环。
(3)适用场景
1)有多个对象可以处理同一个请求,具体哪个对象处理该请求运行时刻在确定。
2)你想在不明确指定接受者的情况下,像多个对象中的一个提交一个请求。
3)可处理一个请求的对象集合应被动态指定。即客户端可以动态的创建职责链来处理请求,还可以改变链中处理者之间的先后次序。