用C++跟你聊聊“职责链模式”

举报
看,未来 发表于 2020/12/29 23:40:01 2020/12/29
【摘要】 文章目录 我要请假职责链模式小故事代码实现职责链的好处 我要请假 那天,咱有点事儿,想请个假。于是和科任老师说了一声,但是科任老师说他这个做不来主,上课离开五分钟还是可以的,但是超过这个时间就要像班主任请示。班主任又说,他的权限只到一早上,像我这样一下子请假一天的,他做不来主,需要向辅导员请示。 就这样绕了一圈,辅导员通过了。 那么这个层层上升的...

在这里插入图片描述

我要请假

那天,咱有点事儿,想请个假。于是和科任老师说了一声,但是科任老师说他这个做不来主,上课离开五分钟还是可以的,但是超过这个时间就要像班主任请示。班主任又说,他的权限只到一早上,像我这样一下子请假一天的,他做不来主,需要向辅导员请示。
就这样绕了一圈,辅导员通过了。

那么这个层层上升的模式,要如何使用代码实现?
用一个switch()?还是用一堆的if···else···?
那如果要对权限进行一波修改呢,班主任只能支持一节课的假,辅导员只能准一上午,要一天就得去找系主任。
这样违反了“单一职责原则”和“开放-封闭原则”。

那怎么办呢?这里推荐“职责链模式”。

其实一开始我不是很喜欢这个东西,感觉没上面用,因为职责需要穷尽。但是后来我转念一想,如果和“桥接模式”组合在一起,那将会有不一样的风景。
这里看“桥接模式

职责链模式

使多个对象都有机会处理请求,从而避免发送者和接收者之间的耦合关系。将这个对象连成一条链,并通过这条链传递该请求,直到有一个对象处理它为止。

在这里插入图片描述

小故事代码实现

//抽象管理者
class Manager
{
protected:
	Manager *m_manager;
	string m_name;
public:
	Manager(Manager *manager, string name):m_manager(manager), m_name(name){}
	virtual void DealWithRequest(string name, int num)  {}
};
//科任老师
class CommonManager: public Manager
{
public:
	CommonManager(Manager *manager, string name):Manager(manager,name) {}
	void DealWithRequest(string name, int num) 
	{
		if(num < 1) { cout<<"老师"<<m_name<<"批准"<<name<<"请假"<<num<<"节课"<<endl;
		}
		else
		{ cout<<"老师"<<m_name<<"无法处理,交由班主任处理"<<endl; m_manager->DealWithRequest(name, num);
		}
	}
};
//班主任
class Majordomo: public Manager
{
public:
	Majordomo(Manager *manager, string name):Manager(manager,name) {}
	void DealWithRequest(string name, int num) 
	{
		if(num < 4) //班主任职权之内
		{ cout<<"班主任"<<m_name<<"批准"<<name<<"请假"<<num<<"节课"<<endl<<endl;
		}
		else
		{ cout<<"班主任"<<m_name<<"无法处理,交由辅导员处理"<<endl; m_manager->DealWithRequest(name, num);
		}
	}
};
//辅导员
class GeneralManager: public Manager
{
public:
	GeneralManager(Manager *manager, string name):Manager(manager,name) {}
	void DealWithRequest(string name, int num)  //辅导员可以处理所有请求
	{
		cout<<"辅导员"<<m_name<<"批准"<<name<<"请假"<<num<<"节课"<<endl<<endl;
	}
};

//测试案例
int main()
{	
	Manager *general = new GeneralManager(NULL, "A"); //设置上级,辅导员暂时没有上级
	Manager *majordomo = new Majordomo(general, "B"); //设置上级
	Manager *common = new CommonManager(majordomo, "C"); //设置上级
	common->DealWithRequest("D",1); common->DealWithRequest("E", 3);
	common->DealWithRequest("F", 6);
	delete common; delete majordomo; delete general;
	return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

职责链的好处

当客户端提交一个请求的时候,请求是沿链传递,直到被处理。
这样就使得接收者和发送者都没有对方的明确信息,且链中对象也不知道链的结构,只能知道他们的上级。
而且可以有链式结构的所有优势。

不过也要当心一个请求一直无法得到处理。

上面的栗子只给出了单一职责,如果要多职责,请自行插入桥接模式。
或者等我下次循环回来的时候写模式混搭的文章,那可能要一个月后了。

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/106200791

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。