责任链模式

✍ dations ◷ 2025-07-01 21:54:29 #软件设计模式

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

以下的日志类(logging)例子演示了该模式。 每一个logging handler首先决定是否需要在该层做处理,然后将控制传递到下一个logging handler。程序的输出是:

  Writing to debug output: Entering function y.  Writing to debug output: Step1 completed.  Sending via e-mail:      Step1 completed.  Writing to debug output: 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

<?phpabstract 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 "Writing to debug output: {$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 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.

相关

  • 普通话普通话是中华人民共和国政府认定的汉语通用语。普通话以北京语音为标准音,以北方话为基础,以典范的现代白话文著作为语法规范。普通话与汉族人口占比最高的官话方言区最为类似
  • 1,2-环己二醇1,2-环己二醇,是从海狸香中发现的一种化学物质。在1,2-环己二醇脱氢酶作用下,反-1,2-环己二醇和烟酰胺腺嘌呤二核苷酸反应,生成2-羟基环己酮,NADH和H+。
  • 腹菌纲腹菌(Gasteroid fungi)是担子菌门中多种真菌的通称,泛指担孢子产生位置在担子果内部,而非担子果表面的类群。这些类群包括马勃、地星、鸟巢菌(英语:Nidulariaceae)、鬼笔与假松露等
  • 陈廷焯陈廷焯(1853年-1892年),字亦峰,又字伯与,丹徒(今江苏省镇江县)人,清代词人、诗词理论家。咸丰三年(1853年)出生,性情磊落,“与人交,表里洞然。无骩骳之习”,清光绪十七年(1891年1月)撰成《白
  • 马赛马拉马赛马拉国家保护区(又译作马塞马拉,Maasai Mara;Masai Mara)是肯尼亚西南部的一个大型猎物禁猎区,位于肯尼亚裂谷省纳罗克附近,与坦桑尼亚北部塞伦盖蒂国家公园无缝对接。名称来
  • 人工岛人工岛是人工建造而非自然形成的岛屿,一般在小岛和暗礁基础上建造,是填海造陆的一种。人工岛的大小不一,由扩大现存的小岛、建筑物或暗礁,或合并数个自然小岛建造而成;有时是独立
  • 性别中立性别中立(英语:Gender neutrality)运动。一般是指推行去性别化的语言、社会政策和其他社会机构(社会结构、性别角色或性别认同)应该避免根据人们的性别来区分性别角色的想法,以避
  • 铜石并用时代铜石并用时代,新石器时代和青铜时代之间的过渡性时期,在该时期主要的工具和武器仍然是石器,但同时出现了少量以红铜器(天然铜器),又称红铜时代、金石并用时代。红铜即天然铜,质地软
  • 中岛 (特里斯坦-达库尼亚)中岛(英语:Middle Island)是一个南大西洋的小岛,是南丁格尔群岛的一部分,为英国海外领土圣赫勒拿、阿森松和特里斯坦-达库尼亚属岛。这个岛是一个无人定居岛。坐标:37°24′40″S
  • 藤子海敏的时间《藤子海敏的时间》(Fuzjko A Pianist of Silence & Solitude)是一部日本纪录片电影,纪录古典钢琴演奏家藤子海敏传奇的一生及对未来的期望,并窥探钢琴家的生活及内心世界。悠扬