责任链模式

✍ dations ◷ 2024-11-05 19:43:15 #软件设计模式

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

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

相关

  • 抗生素抗药性抗生素抗药性(antibiotic resistance)是抗药性的一种形式,借此特性,一些微生物亚群体,通常是细菌种,能够在暴露于一或多种抗生素之下得以生存;对多种抗生素具抗药性的病原体被视为
  • 罗洛·梅罗洛·梅(英语:Rollo May,1909年4月21日-1994年10月22)是一位美国存在主义心理学家。他在1969年期间撰写了具有影响力的书《爱与意志》。他经常被和人本主义心理学与存在主义哲学
  • 五险一金五险一金,指中国大陆地区劳动者所享有的社会保险福利的一种通俗化称呼,其中“五险”是指包括养老保险、医疗保险、工伤保险、失业保险、生育保险在内的五种社会保险,“一金”是
  • 各大区GDP总值本条目为主要年份法国各大区的区内生产总值列表。以法国官方统计资料为依据,以法国本币欧元为基数。为增加可比性,辅以美元折算,美元折算汇率按联合国发布历年各国GDP本币与美
  • 自组装自组装(英语:Self-assembly,或译自我组装)是用来形容一无序系统在没有外部的干预下,由个别部件间之互动(如吸引和排斥,或自发生成化学键),而组成一个有组织的结构之过程。近年自组装
  • 注意力缺陷多动障碍的诊断注意力不足过动症的诊断是根据患者的行为和心理发展的评鉴并且排除毒品、药物的影响、或其他生理或心理的可能造成类似ADHD症状的因素而成。诊断过程通常会将个案的父母意见
  • 泰国科技泰国科技长期以来泰国处于经济较落后的东南亚地区,国政方针为脱离贫困人口的数量当主轴,科技发展较少,至今无科学类诺贝尔奖获得者,科研预算以农牧业和少量化学研发为主。1991年
  • 葡萄牙武装部队葡萄牙武装部队(Forças Armadas Portuguesas),是葡萄牙的军队,包含陆军、海军、空军。葡萄牙总统是最高统帅,但实际上军队是通过国防部长向葡萄牙政府负责。葡萄牙军力上是小型
  • 鄂木斯克州鄂木斯克州(俄语:Омская о́бласть,罗马化:Omskaya oblast)属于西伯利亚联邦管区并位在联邦区西南方,西边和北边与秋明州相邻,南边有临哈萨克斯坦共和国交界,东边则为
  • 2000年夏季奥林匹克运动会帆船比赛2000年夏季奥林匹克运动会的帆船比赛在澳大利亚悉尼举行。