[C++实现 设计模式(10)] : 责任链模式

16 篇文章 0 订阅

情景描述

       中国国代对妇女制定了"三从四德"的道德规范 , “三从"是指"未嫁从父 , 既嫁从夫 , 夫死从子” . 举例来说 , 如果一位女性要出去逛街 , 在她出嫁之前必须征得父亲的同意 , 出家之后必须获得丈夫的许可 , 那丈夫死了怎么办?那就得问问儿子是否允许自己出去逛街 . 我们来分析一下需求 , 女性提出一个请示 , 必然要获得一个答复 , 甭管是同意还是不同意 , 总之是要一个答复 , 而这个答复是唯一的 , 不能说父亲做出一个决断 , 而丈夫也做出一个决断 , 也即是请示传递传出去 , 必然有一个唯一的处理人给出一个答复 .
       我们可以抽象成这样一个结构 , 女性的请求先发送到父亲类 , 父亲类一看是自己要处理的 , 就做出回应处理 , 如果女儿已经出嫁了 , 那就要把这个请求转发到女婿来处理 , 那女婿一旦去天国报到了 , 那就由儿子来处理这个请求了 . 类似于如图所示的顺序处理图 :
在这里插入图片描述

顺序处理的类图 :
在这里插入图片描述

代码实现 :

#include<iostream>
#include<string>
//#include<vld.h>

#define FATHER_LEVEL_REQUEST 1
#define HUSBAND_LEVEL_REQUEST 2
#define SON_LEVEL_REQUEST 3

using namespace std;

//责任链模式
#if 0
//女性接口
class IWomen
{
public:
	//获得个人状况
	 virtual int getType() = 0;

	//获得个人请示 , 你要干什么? 出去逛街?约会?看电影?
	virtual string getRequest() = 0;
};

//古代妇女
class Women : public IWomen
{
	/*
	*通过一个int类型的参数来描述妇女的个人状况
	*1----未出嫁
	*2----出嫁
	*3----夫死
	*/
public:
	//构造函数传递过来的请求
	Women(int _type = 0,string _request = " ") 
	{
		type = _type;
		switch (type)
		{
		case 1:
			request = "女儿的请求是 : "+ _request;
			break;
		case 2:
			request = "妻子的请求是 : "+ _request;
			break;
		case 3:
			request = "母亲的请求是 : "+ _request;
			break;
		default:
			break;
		}
	}
	//获得自己的状况
	int getType()
	{
		return type;
	}
	//获得妇女的请求
	string getRequest()
	{
		return request;
	}
private:
	int type ;
	//妇女的请示
	string request;
};

//有处理权的人员接口
class IHandler
{
public:
	//每个类都要说明自己能处理哪些请求
	IHandler(int n)
		: level(n) , nextHandler(nullptr)
	{}
	//一个女性(女儿 , 妻子或者母亲) 要求逛街 , 你要处理这个请求
	void HandleMessage(IWomen* women) 
	{
		if(women->getType() == level)
			response(women);
		else
		{
			//有后续环节 , 才能把请求往后送
			if(nextHandler != nullptr)
				nextHandler->HandleMessage(women);
			else
				//已经没有后续处理人 , 不用处理
				cout<<"----没地方请示了 , 按不同意处理-----"<<endl;
		}
	}
	/*
	*如果不属于你处理的请求 , 你应该让她找下一个环节的人 , 如女儿出嫁了
	*还想父亲请示是否可以逛街 , 那父亲就应该告诉女儿 , 应该找丈夫请示
	*/
	void setNext(IHandler* _handler)
	{
		nextHandler = _handler;
	}
		

protected:
	//有请示那当然要回应
	virtual void response(IWomen* women) = 0;
private:	
	//能处理的级别
	int level;
	//责任传递 , 下一个责任人是谁	
	IHandler* nextHandler;
};

//父亲类
class Father : public IHandler
{
public:
	Father()
		:IHandler(FATHER_LEVEL_REQUEST)
	{}
	//父亲只处理女儿的请求
	void response(IWomen* women)
	{
		cout<<"-----------------女儿向父亲请示------------------"<<endl;
		cout<<women->getRequest()<<endl;
		cout<<"父亲的答复是 : 同意"<<endl;
	}
};

//丈夫类
class Husband : public IHandler
{
public:
	Husband()
		:IHandler(HUSBAND_LEVEL_REQUEST)
	{}
	void response(IWomen* women)
	{
		cout<<"-----------------妻子向丈夫请示------------------"<<endl;
		cout<<women->getRequest()<<endl;
		cout<<"丈夫的答复是 : 同意"<<endl;
	}
};

//儿子类
class Son : public IHandler
{
public:
	Son()
		:IHandler(SON_LEVEL_REQUEST)
	{}
	void response(IWomen* women)
	{
		cout<<"-----------------母亲向女儿请示------------------"<<endl;
		cout<<women->getRequest()<<endl;
		cout<<"儿子的答复是 : 同意"<<endl;
	}
};



int main()
{
	Women* women1 = new Women(1,"我要出去逛街");
	Women* women2 = new Women(2,"我要出去逛街");
	Women* women3 = new Women(3,"我要出去逛街");

	IHandler* father = new Father();
	IHandler* husband = new Husband();
	IHandler* son = new Son();

	father->setNext(husband);
	husband->setNext(son);

	father->HandleMessage(women1);
	father->HandleMessage(women2);
	father->HandleMessage(women3);

	delete women1; delete women2; delete women3; 
	delete father;
	delete husband;
	delete son;

	return 0;
}

#endif

运行结果 :
在这里插入图片描述

责任链模式的定义

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

       责任链模式的重点在" 链 "上 , 由一条链去处理相似的请求在链中决定谁来处理这个请求 , 并返回相应的结果 .
责任链模式通用类图 :
在这里插入图片描述

责任连模式的结构
抽象的处理者(Handler)实现三个职责:

  • 一是定义一个请求的处理方法handleMessage, 唯一对外开放的方法 ;
  • 二是定义一个链的编排方法setNext,设置下一个处理者;
  • 三是定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务echo .

责任链模式的应用

责任链模式的优点

       责任链模式非常显著的优点是将请求和处理分开 . 请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌 .

责任链模式的缺点

责任链有两个非常显著的缺点:

  • 一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题 .
  • 二是调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂 .
责任链模式的注意事项

       链中节点数量需要控制,避免出现超长链的情况一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能 .

参考书籍 :

                  <<设计模式之禅 第二版>>
                  <<设计模式>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值