设计模式(C++实现)(二十一)——职责链模式

示例问题:

软件在运行时出了问题,需要解决的时候,是不是会出现下述这种很头痛的情况。比如,前端网页无法加载显示图片了,这个问题去找前端的同事处理,前端的同事看了下,说不是他的问题,是中间件传输过来的数据有问题;又找中间件的同事去看,中间件的同事说,是后端java那块发送过来的数据有问题;又去找java开发的同事,java开发的同事说,数据库表结构损坏导致出了问题;又去找数据库的同事解决问题,最终数据库的同事看了下,确实是表结构损坏导致了该问题,然后数据库同事解决了该问题,之后前端网页就可以正常显示图片了。当然这是一种最糟糕的情况,也许在中间环节的同事就判断是他那边的问题,他解决后,最终的问题解决了。

分析:

软件出现问题,这种处理关系是一种链状的形式。每个对象决定该问题是自己处理还是交由下个对象处理。如果在一个类中用if/else来处理这种关系,那么当C++开发参与到这个流程中时,就需要修改这个类的代码了,这样不符合开放封闭原则。如何设计程序能够处理这种链状关系,且当这个链中插入新的环节时,不用修改类的代码?

解决方案:

Chain.h

在该文件中,实现了这个链的环节的处理者的基类CBaseHandler,以及他的子类CWebDeveloper(Web前端开发人员)、CMiddlewareDeveloper(中间件开发人员)、CJavaDeveloper(Java开发人员)、CDBDeveloper(数据库开发人员)。

通过CBaseHandler的SetSuccessor函数来确认下个环节的处理人员,这样可以由客户程序灵活搭配整个链结构。

#pragma once

#include <iostream>

//链的环节处理者基类
class CBaseHandler
{
public:
	CBaseHandler():
	m_pSuccessor(nullptr)
	{

	}

	virtual ~CBaseHandler()
	{

	}

	//处理问题
	virtual void DealProblem(int iData) = 0;

	//设置下个环节
	void SetSuccessor(CBaseHandler* pSuccessor)
	{
		if (nullptr != pSuccessor)
		{
			m_pSuccessor = pSuccessor;
		}
	}

	CBaseHandler* m_pSuccessor;
};

//Web前端开发人员
class CWebDeveloper : public CBaseHandler
{
public:
	CWebDeveloper()
	{

	}

	virtual ~CWebDeveloper()
	{

	}

	void DealProblem(int iData)
	{
		if (iData > 0 && iData <= 10)
		{
			std::cout << "这个问题是前端的问题,我去搞定它" << std::endl;
		}
		else
		{
			if (nullptr != m_pSuccessor)
			{
				m_pSuccessor->DealProblem(iData);
			}
		}
	}
};

//中间件开发人员
class CMiddlewareDeveloper : public CBaseHandler
{
public:
	CMiddlewareDeveloper()
	{

	}

	virtual ~CMiddlewareDeveloper()
	{

	}

	void DealProblem(int iData)
	{
		if (iData > 10 && iData <= 20)
		{
			std::cout << "这个问题是中间件的问题,我去搞定它" << std::endl;
		}
		else
		{
			if (nullptr != m_pSuccessor)
			{
				m_pSuccessor->DealProblem(iData);
			}
		}
	}
};

//Java开发人员
class CJavaDeveloper :public CBaseHandler
{
public:
	CJavaDeveloper()
	{

	}

	virtual ~CJavaDeveloper()
	{

	}

	void DealProblem(int iData)
	{
		if (iData > 20 && iData <= 30)
		{
			std::cout << "这个问题是java后端的问题,我去搞定它" << std::endl;
		}
		else
		{
			if (nullptr != m_pSuccessor)
			{
				m_pSuccessor->DealProblem(iData);
			}
		}
	}

};

//数据库开发人员
class CDBDeveloper : public CBaseHandler
{
public:
	CDBDeveloper()
	{

	}

	virtual ~CDBDeveloper()
	{

	}

	void DealProblem(int iData)
	{
		if (iData > 30 && iData <= 40)
		{
			std::cout << "这个问题是数据库的问题,我去搞定它" << std::endl;
		}
		else
		{
			if (nullptr != m_pSuccessor)
			{
				m_pSuccessor->DealProblem(iData);
			}
		}
	}
};

main.cpp

// main.cpp : 定义控制台应用程序的入口点。
//

#include "Chain.h"


int main()
{
	CBaseHandler* pWebDeveloper = new(std::nothrow) CWebDeveloper();
	CBaseHandler* pMiddlewareDeveloper = new(std::nothrow) CMiddlewareDeveloper();
	CBaseHandler* pJavaDeveloper = new(std::nothrow) CJavaDeveloper();
	CBaseHandler* pDBDeveloper = new(std::nothrow) CDBDeveloper();

	//设置链结构
	pWebDeveloper->SetSuccessor(pMiddlewareDeveloper);
	pMiddlewareDeveloper->SetSuccessor(pJavaDeveloper);
	pJavaDeveloper->SetSuccessor(pDBDeveloper);

	int iArrayProblem[] = { 2, 4, 33, 12 ,23 };
	for (auto Data : iArrayProblem)
	{
		pWebDeveloper->DealProblem(Data);
	}

	if (nullptr != pWebDeveloper)
	{
		delete pWebDeveloper;
		pWebDeveloper = nullptr;
	}
	if (nullptr != pMiddlewareDeveloper)
	{
		delete pMiddlewareDeveloper;
		pMiddlewareDeveloper = nullptr;
	}
	if (nullptr != pJavaDeveloper)
	{
		delete pJavaDeveloper;
		pJavaDeveloper = nullptr;
	}
	if (nullptr != pDBDeveloper)
	{
		delete pDBDeveloper;
		pDBDeveloper = nullptr;
	}

	system("pause");
    return 0;
}

 

运行结果:

职责链模式的使用:

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

职责链模式的关键是当客户提交一个请求时,请求是沿链传递直至有一个具体对象负责处理它。这样使得接受者和发送者都没有对方的明确信息,且链中的对象自己也不知道链的结构,结果是职责链可简化对象的互相连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选者的引用。这也就大大降低了耦合度。

由于是客户来定义链的结构,可随时地增加或者修改处理一个请求的结构。增强了给对象指派职责的灵活性。如在示例程序中,如果要在处理问题的链结构中插入一个C++开发人员,则只需要再增加一个C++开发人员的子类,然后由客户程序修改设置链结构的地方即可。但是需要注意这样配置虽然很灵活,不过需要当心——一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,这就很糟糕了。需要事先考虑全面。

职责链模式最重要需要关注的两点:

1)为每个对象设置后继者

2)每个对象处理时,需做出判断,是可以处理这个请求,还是必须要“推卸责任”,转移给后继者去处理。

何时使用职责链模式:

当一个请求是沿链传递,链的每一个环节都有可能处理它。

 

返回目录:设计模式(C++实现)(总)

上一篇:设计模式(C++实现)(二十)——命令模式

下一篇:设计模式(C++实现)(二十二)——中介者模式

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值