设计模式系列2-----C++实现责任链模式(Chain of Responsibility)

什么是责任链模式?

      wikipedia的定义为:CoR pattern consists of a source of command objects and a series of processing objects. Each processing object contains a set of logic that describes the types of command objects that it can handle, and how to pass off those that it cannot handle to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.

      换言之,一项任务可能有多个可以处理者,这时将这些处理者组织成链状,只需要将这项任务交给链头,这项任务便在这个处理链(责任链)中传递。它可以在得到某一处理者处理后停止传递,也可以不论是否有处理都传递给所有的处理者。可以用下图表示:

      使用责任链模式,请求任务者便不需要了解各个具体的处理者,也不需要了解他们的结构,而且责任链也可以动态的增加或删除处理节点。

 

类图结构:

 

Example:

      下面的例子应用场景是描述公司的采购批单过程,经理、总监、、总裁能批准的额度不一样,当某一级的处理者无法处理的时候便交给他的上级处理。完整代码如下:

#include <iostream>
using namespace std;

class PurchasePower
{
public:
	PurchasePower(PurchasePower* pSuccessor = NULL) : m_pSuccessor(pSuccessor) {}

	void setSuccessor(PurchasePower* pSuccessor)
	{
		this->m_pSuccessor = pSuccessor;
	}

	virtual void processRequest(float amount) = 0;

protected:
	PurchasePower* m_pSuccessor;
};

class Manager : public PurchasePower
{
public:
	Manager(PurchasePower* pSuccessor = NULL) : PurchasePower(pSuccessor) {}

	virtual void processRequest(float amount)
	{
		const float ALLOWABLE = 500.0f;

		cout << "Manager received request " << amount << endl;
		if (amount < ALLOWABLE)
			cout << "Manager processed request " << amount << "\n\n";
		else if (m_pSuccessor)
		{
			cout << "Manager passed on request " << amount << endl;
			m_pSuccessor->processRequest(amount);
		}
	}
};

class Director : public PurchasePower
{
public:
	Director(PurchasePower* pSuccessor = NULL) : PurchasePower(pSuccessor) {}

	virtual void processRequest(float amount)
	{
		const float ALLOWABLE = 1000.0f;

		cout << "Director received request " << amount << endl;
		if (amount < ALLOWABLE)
			cout << "Director processed request " << amount << "\n\n";
		else if (m_pSuccessor)
		{
			cout << "Director passed on request " << amount << endl;
			m_pSuccessor->processRequest(amount);
		}
	}
};

class CEO : public PurchasePower
{
public:
	CEO(PurchasePower* pSuccessor = NULL) : PurchasePower(pSuccessor) {}

	virtual void processRequest(float amount)
	{
		const float ALLOWABLE = 10000.0f;

		cout << "CEO received request " << amount << endl;
		if (amount < ALLOWABLE)
			cout << "CEO processed request " << amount << "\n\n";
		else if (m_pSuccessor)
		{
			cout << "CEO passed on request " << amount << endl;
			m_pSuccessor->processRequest(amount);
		}
	}
};

int main()
{
	Manager* pManager = new Manager();
	Director* pDirector = new Director();
	CEO* pCEO = new CEO();
	pManager->setSuccessor(pDirector);
	pDirector->setSuccessor(pCEO);

	float amount;
	while (cin >> amount)
	{
		pManager->processRequest(amount);
	}

	delete pCEO;
	delete pDirector;
	delete pManager;

	return 0;
}

      运行结果如下:

image

     

      可以看到最后一个请求没有得到解决,这是责任链的缺点之一。当然也可以总是在责任链的最后加一个通用处理者。

      另外传统责任链的一个缺点是如果程序员忘记了调用下一级的处理者,请求便终止,程序并不能保证这点。这篇文章The Chain of Responsibility pattern's pitfalls and improvements用了类似Template Method模式的方法解决了这个问题。

 

参考资料:

Wikipedia: Chain-of-responsibility pattern

The Chain of Responsibility pattern's pitfalls and improvements

<<Head First Design Pattern>>

<<Design Patterns—Elements of Reusable Object-Oriented Software>>

posted on 2011-12-04 17:15  GraphicsMe  阅读(600)  评论(0编辑  收藏  举报

导航