责任链模式

责任链模式在物件导向程式设计里是一种软件设计模式，它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象，它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。
结构.
在上面的UML类图中，codice_1类不直接提及到特定的接收者类。codice_1转而提及到了codice_3接口，通过它来处理一个请求（codice_4），这使得codice_1独立于处理这个请求的接收者。codice_6、codice_7和codice_8类实现了codice_3接口，它们要么处理要么转发一个请求（依赖于运行时条件）。
UML序列图展示了运行时交互：在这个例子中，codice_1对象调用codice_11于codice_12对象之上（它具有类型codice_3）。codice_12转发这个请求至codice_15，它接着转发这个请求至codice_16，它处理了这个请求。
代码示例.
C++.
《设计模式》书中早于C++98的例子的C++11实现：
typedef int Topic;
constexpr Topic NO_HELP_TOPIC = -1;
// defines an interface for handling requests.
class HelpHandler { // Handler
public:
 HelpHandler(HelpHandler* h = nullptr, Topic t = NO_HELP_TOPIC)
 virtual bool hasHelp() {
 return topic != NO_HELP_TOPIC;
 virtual void handleHelp() {
 std::cout « "HelpHandler::handleHelp\n";
 // (optional) implements the successor link.
 if (successor != nullptr) {
 successor-&gt;handleHelp();
 virtual ~HelpHandler() = default;
 HelpHandler(const HelpHandler&amp;) = delete; // rule of three
 HelpHandler&amp; operator=(const HelpHandler&amp;) = delete;
private:
 HelpHandler* successor;
 Topic topic;
class Widget : public HelpHandler {
public:
 Widget(const Widget&amp;) = delete; // rule of three
 Widget&amp; operator=(const Widget&amp;) = delete;
protected:
 Widget(Widget* w, Topic t = NO_HELP_TOPIC) 
 : HelpHandler(w, t), parent(nullptr) {
 parent = w;
private:
 Widget* parent;
// handles requests it is responsible for.
class Button : public Widget { // ConcreteHandler
public:
 virtual void handleHelp() {
 // if the ConcreteHandler can handle the request, it does so; otherwise it forwards the request to its successor.
 std::cout « "Button::handleHelp\n";
 if (hasHelp()) {
 // handles requests it is responsible for.
 } else { 
 // can access its successor.
 HelpHandler::handleHelp();
class Dialog : public Widget { // ConcreteHandler
public:
 Dialog(std::shared_ptr&lt;HelpHandler&gt; h, Topic t = NO_HELP_TOPIC) : Widget(nullptr) {
 setHandler(h.get(), t);
 virtual void handleHelp() {
 std::cout « "Dialog::handleHelp\n";
 // Widget operations that Dialog overrides...
 if(hasHelp()) {
 // offer help on the dialog
 } else {
 HelpHandler::handleHelp();
class Application : public HelpHandler {
public:
 virtual void handleHelp() {
 std::cout « "Application::handleHelp\n";
 // show a list of help topics
};
int main() {
 constexpr Topic PRINT_TOPIC = 1;
 constexpr Topic PAPER_ORIENTATION_TOPIC = 2;
 constexpr Topic APPLICATION_TOPIC = 3;
 // The smart pointers prevent memory leaks.
 std::shared_ptr&lt;Application&gt; application = std::make_shared&lt;Application&gt;(APPLICATION_TOPIC);
 std::shared_ptr&lt;Dialog&gt; dialog = std::make_shared&lt;Dialog&gt;(application, PRINT_TOPIC);
 std::shared_ptr&lt;Button&gt; button = std::make_shared&lt;Button&gt;(dialog, PAPER_ORIENTATION_TOPIC);
 button-&gt;handleHelp();
Python.
下面是Python的例子：
from abc import ABC, abstractmethod
topic_list = [
 'Application topic', 'Print topic',
 'Paper orientation topic']
class HelpHandler(ABC):
 def __init__(self, handler, topic=None):
 assert topic in topic_list
 self.__successor = handler
 self.__topic = topic
 def has_help(self, topic): 
 return self.__topic == topic
 @abstractmethod
 def handle_help(self, topic):
 if self.__successor is None:
 print(f"No help with {topic}")
 else:
 self.__successor.handle_help(topic)
class Application(HelpHandler):
 def __init__(self, topic=None):
 super().__init__(None, topic)
 def handle_help(self, topic):
 if self.has_help(topic):
 print(f"Application: help with {topic}")
 else:
 super().handle_help(topic)
class Widget(HelpHandler):
 def __init__(self, parent, topic=None):
 self.parent = parent
 super().__init__(parent, topic)
 def draw(self): pass
class Dialog(Widget):
 def handle_help(self, topic):
 if self.has_help(topic):
 print(f"Dialog: help with {topic}")
 else:
 super().handle_help(topic)
class Button(Widget):
 def handle_help(self, topic):
 if self.has_help(topic):
 print(f"Button: help with {topic}")
 else:
 super().handle_help(topic)
其执行：
»&gt; application = Application(topic_list[0])
»&gt; dialog = Dialog(application, topic_list[1])
»&gt; button = Button(dialog, topic_list[2])
»&gt; button.handle_help(topic_list[2])
Button: help with Paper orientation topic
»&gt; button.handle_help(topic_list[1])
Dialog: help with Print topic
»&gt; button.handle_help(topic_list[0])
Application: help with Application topic
»&gt; button.handle_help('No such topic')
No help with No such topic
Java.
下面是Java的日志类(logging)例子演示了该模式。 每一个logging handler首先决定是否需要在该层做处理，然后将控制传递到下一个logging handler。程序的输出是:
 Writting to stdout: Entering function y.
 Writting to stdout: Step1 completed.
 Sending via e-mail: Step1 completed.
 Writting to stdout: An error has occurred.
 Sending via e-mail: An error has occurred.
 Writing to stderr: An error has occurred.
注意：该例子不是日志类的推荐实现方式。
同时，需要注意的是，通常在责任链模式的实现中，如果在某一层已经处理了这个logger，那么这个logger就不会传递下去。在我们这个例子中，消息会一直传递到最底层不管它是否已经被处理。
import java.util.*;
abstract class Logger {
 public static int ERR = 3;
 public static int NOTICE = 5;
 public static int DEBUG = 7;
 protected int mask;
 // The next element in the chain of responsibility
 protected Logger next;
 public Logger setNext(Logger l) {
 next = l;
 return this;
 public final void message( String msg, int priority) {
 if (priority &lt;= mask) {
 writeMessage(msg);
 if (next != null) {
 next.message(msg, priority);
 
 protected abstract void writeMessage(String msg);
class StdoutLogger extends Logger {
 protected void writeMessage(String msg) {
 System.out.println("Writting to stdout: " + msg);
class EmailLogger extends Logger {
 protected void writeMessage(String msg) {
 System.out.println("Sending via email: " + msg);
class StderrLogger extends Logger {
 protected void writeMessage(String msg) {
 System.out.println("Sending to stderr: " + msg);
public class ChainOfResponsibilityExample {
 public static void main(String[] args) {
 // Build the chain of responsibility
 Logger l = new StdoutLogger(Logger.DEBUG).setNext(
 new EmailLogger(Logger.NOTICE).setNext(
 new StderrLogger(Logger.ERR)));
 // Handled by StdoutLogger
 l.message("Entering function y.", Logger.DEBUG);
 // Handled by StdoutLogger and EmailLogger
 l.message("Step1 completed.", Logger.NOTICE);
 // Handled by all three loggers
 l.message("An error has occurred.", Logger.ERR);
PHP.
下面是PHP的例子：
&lt;?php
abstract class Logger {
 const ERR = 3;
 const NOTICE = 5;
 const DEBUG = 7;
 protected $mask;
 protected $next; // The next element in the chain of responsibility
 public function setNext(Logger $l) {
 $this-&gt;next = $l;
 return $this;
 abstract public function message($msg, $priority);
class DebugLogger extends Logger {
 public function __construct($mask) {
 $this-&gt;mask = $mask;
 public function message($msg, $priority) {
 if ($priority &lt;= $this-&gt;mask) {
 echo "Writting to stdout: {$msg}\n";
 if (false == is_null($this-&gt;next)) {
 $this-&gt;next-&gt;message($msg, $priority);
class EmailLogger extends Logger {
 public function __construct($mask) {
 $this-&gt;mask = $mask;
 public function message($msg, $priority) {
 if ($priority &lt;= $this-&gt;mask) {
 echo "Sending via email: {$msg}\n";
 if (false == is_null($this-&gt;next)) {
 $this-&gt;next-&gt;message($msg, $priority);
class StderrLogger extends Logger {
 public function __construct($mask) {
 $this-&gt;mask = $mask;
 public function message($msg, $priority) {
 if ($priority &lt;= $this-&gt;mask) {
 echo "Writing to stderr: {$msg}\n";
 if (false == is_null($this-&gt;next)) {
 $this-&gt;next-&gt;message($msg, $priority);
class ChainOfResponsibilityExample {
 public function __construct() {
 // build the chain of responsibility
 $l = new DebugLogger(Logger::DEBUG);
 $e = new EmailLogger(Logger::NOTICE);
 $s = new StderrLogger(Logger::ERR);
 $e-&gt;setNext($s);
 $l-&gt;setNext($e);
 $l-&gt;message("Entering function y.", Logger::DEBUG); // handled by DebugLogger
 $l-&gt;message("Step1 completed.", Logger::NOTICE); // handled by DebugLogger and EmailLogger
 $l-&gt;message("An error has occurred.", Logger::ERR); // handled by all three Loggers
new ChainOfResponsibilityExample();