责任链模式

✍ dations ◷ 2025-09-14 19:32:14 #软件设计模式

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

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

相关

  • 博科尼大学博科尼大学全称Università Commerciale Luigi Bocconi(英语:Bocconi University),博科尼大学是意大利第一家教授经济学高等教育的学院。该大学也是欧洲最重要的商学院之一,它的
  • 国防高等研究计划署国防先进研究计划署(英语:Defense Advanced Research Projects Agency,缩写:DARPA),前称先进研究计划署(英语:Advanced Research Projects Agency,缩写:ARPA),是美国国防部负责研发军用
  • 最小作用量原理在物理学里, 最小作用量原理(英语:least action principle),或更精确地,平稳作用量原理(英语:stationary action principle),是一种变分原理,当应用于一个机械系统的作用量时,可以得到此
  • 雷蒙德·阿姆斯·斯普鲁恩斯第一次世界大战第二次世界大战雷蒙德·艾姆斯·斯普鲁恩斯(Raymond Ames Spruance,1886年7月3日-1969年12月23日,或译为雷蒙德·史普劳恩斯),第二次世界大战时期美国海军将领(最终
  • 五旬节五旬节,即基督教的圣灵降临日(亦称圣神降临节),源自犹太人三大节期之一七七节。犹太教按犹太历守节期,纪念以色列人出埃及后第五十天〔由出埃及记19:1之记载:以色列人出埃及以后,满
  • 美国宪法第13修正案宪法正文I ∙ II ∙ III ∙ IV ∙ V ∙ VI ∙ VII其它修正案 XI ∙ XII ∙ XIII ∙ XIV ∙ XV XVI ∙ XVII ∙ XVIII ∙ XIX ∙ XX XXI ∙ XXII ∙ XXIII ∙
  • 肺癌分期肺癌是依照 TNM 系统(tumor-node-metastasis)分期,T代表肿瘤本身的大小或是侵犯范围,N代表周边淋巴结侵犯及转移,M代表远端转移。临床上,医师会依据影像检查、病理报告等资讯决定T
  • 工党 (荷兰)工党(荷兰语:Partij van de Arbeid,缩写为PvdA)是荷兰一个中间偏左社会民主主义的政党。它也是社会党国际的成员团体。荷兰工党成立于1946年2月9日,由三个政党合并而成,成立动机在
  • 麻内麻内(拉丁语:Manes),古罗马宗教中的善良灵魂。名词可能源于拉丁文中的“好(Manus)”,指冥府神灵或已逝亲人的灵魂,与之相对的是雷姆雷斯,代表不安的、作祟的恶灵。古罗马人会在二月的
  • 加尔默罗会修道院 (布拉格)加尔默罗会修道院(Klášter bosých karmelitánek)是布拉格的一座巴洛克修道院,位于城堡区,城堡广场西南侧。修道院的所在地,曾经是诗人Bohuslav Hasištejnský z Lobkovic的