【C++设计模式】责任链模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxh2075/article/details/82868466
#ifndef __CHAIN_H__
#define __CHAIN_H__

#include <string>

//【说明】
// 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

//【定义】
// 责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。

//【角色】
// 1)抽象处理者(Handler):1) 该角色定义一个模板方法处理请求,使请求在链上传递。
//                          2) 内部包含下一个处理者对象的引用,定义一个方法来设定和返回对下一个处理者的引用。
//                          3) 抽象出真正处理请求的接口,给子类覆盖用。

// 2)具体处理者(Concrete Handler):继承抽象处理者,实现真正处理请求的业务逻辑。

//【意义】
// 责任链弱化了发出请求的人和处理请求的人之间的关系,将请求沿着链传递,让每个处理者更专注于自己的工作。
// 责任链模式在实现时,它的链的形状不是职责链本身建立和维护的,而是由客户进行创建的,这就大大提高了责任链的灵活性。
// 降低程序的性能。每个请求都是从链头遍历到链尾,当链比较长的时候,性能会大幅下降。

//【示例】

//待解决的问题
class Trouble
{
public:
	Trouble(int id) : m_id(id){ }

	int  GetID();

private:
	int  m_id;
};

//处理问题的抽象类
class Support
{
public:
	Support(){ }

	Support(const std::string & name) : m_name(name), m_next(NULL){ }

	virtual ~Support(){ }

public:

	Support * SetNext(Support * support);

	//模板方法
	void Proc(Trouble &trouble);

	//对上层提供接口
	virtual int Resolve(Trouble &trouble) = 0;

private:
	std::string m_name;
	Support *   m_next;
};

//处理问题编号小于limit值的类
class LimitSupport : public Support
{
public:
	LimitSupport(const std::string & name, int limit) : Support(name), m_limit(limit){ }

	virtual int Resolve(Trouble &trouble);

private:
	int  m_limit;
};

//处理问题编号为基数的类
class OddSupport : public Support
{
public:
	OddSupport(const std::string & name) : Support(name){ }

	virtual int Resolve(Trouble &trouble);
};

//处理问题编号为特定值的类
class SepcialSupport : public Support
{
public:
	SepcialSupport(const std::string & name, int id): Support(name), m_id(id){ }

	virtual int Resolve(Trouble &trouble);

private:
	int  m_id;
};

void TestChain();


#endif

#include "Chain.h"

int Trouble::GetID()
{
	return m_id;
}

Support * Support::SetNext(Support * support)
{
	this->m_next = support;
	return this->m_next;
}

void Support::Proc(Trouble &trouble)
{
	if (Resolve(trouble) == 0)
	{
		printf("the %d trouble is resolved by %s\n", trouble.GetID(), this->m_name.c_str());
	}
	else if (this->m_next)
	{
		this->m_next->Proc(trouble);
	}
	else
	{
		printf("the %d trouble cannot be resolved\n", trouble.GetID());
	}
}

int LimitSupport::Resolve(Trouble &trouble)
{
	if (trouble.GetID() < this->m_limit)
	{
		return 0;
	}

	return 1;
}

int OddSupport::Resolve(Trouble &trouble)
{
	if (trouble.GetID() % 2 == 1)
	{
		return 0;
	}

	return 1;
}

int SepcialSupport::Resolve(Trouble &trouble)
{
	if (trouble.GetID() == this->m_id)
	{
		return 0;
	}

	return 1;
}

void TestChain()
{
	Support * alice = new LimitSupport("alice", 12);

	Support * bob = new SepcialSupport("bob", 15);

	Support * tom = new OddSupport("tom");

	alice->SetNext(bob)->SetNext(tom);	

	for (int i=0; i<20; i++)
	{
		Trouble trouble(i);
		alice->Proc(trouble);
	}

	delete alice;
	delete bob;
	delete tom;

	return;
}

猜你喜欢

转载自blog.csdn.net/zxh2075/article/details/82868466