【设计模式】责任链模式

责任链模式是一种软件设计模式。它包括了一些命令对象和一系列的处理对象。

每个处理对象决定它能处理哪些命令对象。它也知道怎样将它不能处理的命令对象传递给该链中的下一个处理对象。

该模式还描写叙述了往该处理链的末尾加入新的处理对象的方法。

责任链模式的UML图例如以下:



以下是一个用C++描写叙述的责任链模式的样例:

#include <iostream>
#include <string>

using namespace std;

// 抽象类,定义处理请求的接口
class Logger {
public:
	static const int DEBUG = 1;
	static const int NOTICE = 2;
	static const int ERR = 3;

	// 设置责任链下一个成员
	void setNext(Logger *log)
	{
		next = log;
	}

	// 依据优先级决定处理消息或传递给下一个处理者
	void message(string msg, int priority)
	{
		if (priority <= mask)
			writeMessage(msg);	
		else if (next != NULL)
			next->message(msg, priority);
	}
protected:
	int mask;
	// The next element in the chain of responsibility
	Logger *next;
	virtual void writeMessage(string msg) = 0;
};

// 详细处理者
class StdoutLogger : public Logger {
public:
	StdoutLogger(int m)
	{
		mask = m;
	}

protected:
	void writeMessage(string msg)
	{
		cout << "Writting to stdout: " << msg << endl;
	}
};

// 详细处理者
class EmailLogger : public Logger {
public:
	EmailLogger(int m)
	{
		mask = m;
	}

protected:
	void writeMessage(string msg)
	{
		cout << "Sending via email: " << msg << endl;
	}
};

// 详细处理者
class StderrLogger : public Logger
{
public:
	StderrLogger(int m)
	{
		mask = m;
	}
protected:
	void writeMessage(string msg)
	{
		cout << "Sending to stderr: " << msg << endl;
	}
};


int main()
{
	Logger *log1 = new StdoutLogger(Logger::DEBUG);
	Logger *log2 = new EmailLogger(Logger::NOTICE);
	Logger *log3 = new StderrLogger(Logger::ERR);

	// Build the chain of responsibility
	log1->setNext(log2);
	log2->setNext(log3);

	// Handled by StdoutLogger
	log1->message("Hello world.", Logger::DEBUG);

	// Handled by EmailLogger
	log1->message("Sending a Email.", Logger::NOTICE);

	// Handled by StderrLogger
	log1->message("An error has occurred.", Logger::ERR);

	system("pause");
	return 0;
}

执行结果:


上面的样例中,我们建立了三个处理消息的对象。依据内容的优先级分别把内容输出到标准输出、邮件、标准错误。当一个处理对象无法处理这个等级的内容时,将自己主动传递给责任链中的下一个处理者处理。也就是说,当客户提交一个请求时,请求是沿着责任链传递直至一个详细的负责处理内容的对象。责任链的长处在于,处理内容的对象是通过链表连接起来的。添加或改动责任链是很方便灵活的。实际上,责任链模式就是把if-else结构改成了链表结构来处理不同的消息,大大减少了代码的耦合度。


參考:

维基百科

《大话设计模式》第24章

原文地址:https://www.cnblogs.com/yjbjingcha/p/6816405.html