责任链模式

✍ dations ◷ 2025-07-02 09:36:24 #软件设计模式

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

以下的日志类(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.

相关

  • 齿牙齿存在于很多脊椎动物(鸟类除外)的头部(或口部)内、功能用于咀嚼食物的钙化组织。肉食性动物尤其倚赖牙齿进行猎食或搏斗、御敌。牙齿的构成成分不是骨骼,而是由动物体内不同
  • 斯坦曼拉尔夫·马文·斯坦曼(英语:Ralph Marvin Steinman,1943年1月14日-2011年9月30日),美国洛克菲勒大学的免疫学家和细胞生物学家。他在1973年提出了树突状细胞的概念与其在后天免疫
  • 八大地狱八大地狱(又名八热地狱),是佛教所谓四类地狱之一。八大地狱位于地心,最底层就是阿鼻地狱。而每一个火地狱又各自拥有十六个小地狱。地狱有所谓“四类十八地狱”,四类即八大地狱、
  • 离岛离岛或外岛意指远离主体或大陆的岛屿。不同地区的离岛:
  • 曹时曹时(前2世纪-前131年),又作曹寿,西汉第四代平阳侯。娶汉景帝之女阳信长公主为妻。曹时是西汉开国功臣曹参的曾孙。汉景帝四年(前154年),曹时继承平阳侯爵位。元光四年(前131年)平阳侯
  • 外部成本外部性(英语:Externality)是指个体经济单位的行为对社会或者其他个人部门造成了影响(例如环境污染)却没有承担相应的义务或获得回报,亦称外部成本、外部效应或溢出效应。这种外部
  • 轰炸拉包尔 (1943年11月)盟军于1943年11月对日军在拉包尔的主要基地之巡洋舰队进行空中攻击。为了应对盟军入侵布干维尔岛,日军从日本向拉包尔派出强大的巡洋舰队,准备在一天晚上,对盟军的运输及支援舰
  • 萧氏节孝坊萧氏节孝坊位于台南市中西区,是中华民国直辖市定古迹。是台南市仅存的四大石坊之一,也是唯一仅存的节孝牌坊。萧氏节孝坊位于昔日台湾府城西定坊海防同知衙门(二府口)前,是清嘉庆
  • 阿穆尔河畔共青城阿穆尔河畔共青城(俄语:Комсомо́льск-на-Аму́ре,转写:Komsomolsk-na-Amure),简称共青城,是位于俄罗斯东部哈巴罗夫斯克边疆区黑龙江畔的一座城市,距离首府伯力4
  • 磨损作用 (牙科)磨损作用(abrasion),牙科上称为牙磨损,指受外来元素形成的机械力(mechanical forces),导致牙齿结构脱落。外来元素包括牙刷、牙签、牙线等。