**责任链模式**在物件導向程式設計裡是一种软件设计模式，它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象，它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。

代码示例
----

### 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 <= mask ) 
 {
 writeMessage( msg );
 if ( next != null )
 {
 next.message( msg, priority );
 }
 }
 }
 
 protected abstract void writeMessage( String msg );

}

class StdoutLogger extends Logger 
{

 public StdoutLogger( int mask ) { this.mask = mask; }

 protected void writeMessage( String msg )
 {
 System.out.println( "Writting to stdout: "+ msg );
 }
}

class EmailLogger extends Logger 
{

 public EmailLogger( int mask ) { this.mask = mask; }

 protected void writeMessage( String msg )
 {
 System.out.println( "Sending via email: "+ msg );
 }
}

class StderrLogger extends Logger 
{

 public StderrLogger( int mask ) { this.mask = mask; }

 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
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->next = $l;
		return $this;
	}

	abstract public function message($msg, $priority);
}

class DebugLogger extends Logger {
	public function \_\_construct($mask) {
		$this->mask = $mask;
	}

	public function message($msg, $priority) {
		if ($priority <= $this->mask) {
			echo "Writting to stdout: {$msg}\n";
		}

		if (false == is\_null($this->next)) {
			$this->next->message($msg, $priority);
		}
	}
}

class EmailLogger extends Logger {
	public function \_\_construct($mask) {
		$this->mask = $mask;
	}

	public function message($msg, $priority) {
		if ($priority <= $this->mask) {
			echo "Sending via email: {$msg}\n";
		}

		if (false == is\_null($this->next)) {
			$this->next->message($msg, $priority);
		}
	}
}

class StderrLogger extends Logger {
	public function \_\_construct($mask) {
		$this->mask = $mask;
	}

	public function message($msg, $priority) {
		if ($priority <= $this->mask) {
			echo "Writing to stderr: {$msg}\n";
		}

		if (false == is\_null($this->next)) {
			$this->next->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->setNext($s);
		$l->setNext($e);

		$l->message("Entering function y.",		Logger::DEBUG);		// handled by DebugLogger
		$l->message("Step1 completed.",			Logger::NOTICE);	// handled by DebugLogger and EmailLogger
		$l->message("An error has occurred.",	Logger::ERR);		// handled by all three Loggers
	}
}

new ChainOfResponsibilityExample();
?>

```

### Visual Prolog

这是一个用mutex保护对于stream的操作的真实例子。

First the outputStream interface (a simplified version of the real one):

```
interface outputStream
   predicates
      write : (...).
      writef : (string FormatString, ...).
end interface outputStream
```

This class encapsulates each of the stream operations the mutex. The **finally** predicate is used to ensure that the mutex is released no matter how the operation goes (i.e. also in case of exceptions). The underlying mutex object is released by a *finalizer* in the mutex class, and for this example we leave it at that.

```
class outputStream_protected : outputStream
   constructors
      new : (string MutexName, outputStream Stream).
end class outputStream_protected

#include @"pfc\multiThread\multiThread.ph"

implement outputStream_protected
   facts
      mutex : mutex.
      stream : outputStream.
   clauses
      new(MutexName, Stream) :-
         mutex := mutex::createNamed(MutexName, false), % do not take ownership
         stream := Stream.
   clauses
      write(...) :-
         _ = mutex:wait(),  % ignore wait code in this simplified example
         finally(stream:write(...), mutex:release()).

   clauses
      writef(FormatString, ...) :-
         _ = mutex:wait(),  % ignore wait code in this simplified example
         finally(stream:writef(FormatString, ...), mutex:release()).
end implement outputStream_protected
```

**Usage example**.

The **client** uses an **outputStream**. Instead of receiving the **pipeStream** directly, it gets the protected version of it.

```
#include @"pfc\pipe\pipe.ph"

goal
   Stream = pipeStream::openClient("TestPipe"),
   Protected = outputStream_protected::new("PipeMutex", Stream),
   client(Protected),
   Stream:close().
```

另見
--

* Interception pattern
* Interceptor pattern
* Single responsibility principle

外部链接
----

* Article "The Chain of Responsibility pattern's pitfalls and improvements" by Michael Xinsheng Huang
* Article "Follow the Chain of Responsibility" by David Geary
* Article "Pattern Summaries: Chain of Responsibility" by Mark Grand
* CoR overview （页面存档备份，存于）
* Behavioral Patterns - Chain of Responsibility Pattern
* Descriptions from Portland Pattern Repository
* Apache Jakarta Commons Chain

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
软件设计模式 |
| --- |
|  |
| 设计模式 | 

|  |  |
| --- | --- |
| 创建型 | 
* 抽象工厂
* 生成器
* 工厂方法
* 惰性初始
* 原型
* 单例

 |
|  |
| 结构型 | 
* 适配器
* 桥接
* Composite（英语：）
* 修饰
* 外观
* 享元
* 代理

 |
|  |
| 行为型 | 
* 责任链
* 命令
* Interpreter（英语：）
* 迭代器
* 中介者
* Memento（英语：）
* 观察者
* Specification（英语：）
* State（英语：）
* 策略
* 模板方法
* 访问者

 |

 |
|  |
| 并行模式 | 
* 主动对象（英语：）
* 阻止（英语：）
* Binding properties（英语：）
* 双重检查锁定模式
* 异步方法调用
* Future与promise
* Guarded suspension（英语：）
* Join（英语：）
* 锁
* Messaging（英语：）
* 监视器
* Proactor（英语：）
* 反应器
* 读写锁
* 调度
* 线程池
* 线程局部存储

 |
|  |
| 架构模式 | 
* ADR（英语：）
* 主动记录
* Broker（英语：）
* 主從式架構
* cbd
* DAO
* DDD
* Data transfer object（英语：）
* Front controller（英语：）
* Identity map（英语：）
* Interceptor（英语：）
* 控制反转
* MVC
* 微服務
* MVP
* 單體式應用程式
* 多层架构
* *n*-tier（英语：）
* Naked objects（英语：）
* P2P
* 发布/订阅
* REST
* SOA
* Specification（英语：）

 |
|  |
| 云分布式 | 
* 断路器
* CQRS（英语：）
* 补偿交易（英语：）
* 索引表
* 领导者选举（英语：）
* MapReduce
* 物化视图（英语：）
* 管道
* 过滤器（英语：）
* 发布/订阅
* 分片（英语：）
* 节流（英语：）

 |
|  |
| 其他模式 | 
* Blackboard（英语：）
* Business delegate（英语：）
* Composite entity（英语：）
* 委托
* 依赖注入
* Intercepting filter（英语：）
* 惰性載入
* Method chaining（英语：）
* 模拟对象
* 空对象
* 对象池
* Servant（英语：）
* Twin（英语：）
* Type tunnel（英语：）

 |
|  |
| 书籍 | 
* 设计模式：可复用面向对象软件的基础
* 企业集成模式（英语：）

 |
|  |
| 人物 | 
* 克里斯托佛·亚历山大
* 埃里希·伽瑪
* Ralph Johnson（英语：）
* John Vlissides（英语：）
* 葛來迪·布區
* 肯特·貝克
* 沃德·坎宁安
* 马丁·福勒
* Robert Martin（英语：）
* Jim Coplien（英语：）
* Douglas Schmidt（英语：）
* Linda Rising

 |
|  |
| 社区 | 
* The Hillside Group（英语：）
* The Portland Pattern Repository（英语：）

 |

 |