版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}