责任链模式

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

**代码示例**

**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 

**PHP**
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 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 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 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 date=20080422185544 -  Behavioral Patterns - Chain of Responsibility Pattern-  Descriptions from Portland Pattern Repository-  Apache Jakarta Commons Chain