责任链模式

✍ dations ◷ 2024-09-20 15:20:39 #软件设计模式

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

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

相关

  • 子囊菌门子囊菌门(学名:Ascomycota)是真菌界中种类最多的一个门,其中除酵母亚门为单细胞外,其余种类都是多细胞的,有分枝、有隔的菌丝组成的。它与担子菌门(Basidiomycota)一起构成了双核亚
  • Fasciolopsis buski布氏姜片虫(学名:Fasciolopsis buski),简称姜片虫,是一种外观极像薄切姜片的中、大型寄生虫。为完成一代生活,这种虫必须在环境适当的淡水螺体内发育,再以常见的水生植物作第二轮的
  • 虹膜异色虹膜异色症,另称异色瞳(英语:Heterochromia iridum),是一种身体异常状况,指两眼的虹膜呈现不同颜色的性状。眼睛的颜色,特别是虹膜的颜色,是由虹膜组织的色素沉淀及分布决定的;因此,在
  • 罗伯特·麦克阿瑟罗伯特·麦克阿瑟(Robert MacArthur,1930年4月7日-1972年11月1日)是一位美国生态学家,主要研究种群生态学和群落生态学(英语:Community (ecology))。麦克阿瑟在马尔伯勒学院(英语:Marl
  • 千叶大学千叶大学是日本的一所国立大学,位于千叶县千叶市。 本部地址是千叶市稻毛区弥生町1-33。日文中简称:千叶大(ちばだい, chibadai) 而其他三个校区分别为于:亥鼻、松戸、柏之叶。
  • 氢氧化物氢氧离子,旧称沎,化学符号为OH-。其中氢和氧之间以共价键连接,整体带一单位的负电荷。常常与不同的元素组成氢氧化物。一个氧原子和一个氢原子以共价键结合之后,通常以两种方式
  • 汗水汗液,或汗,是由人等高等动物透过汗腺所分泌出的液体。汗的分泌受到植物性神经系统调节。汗液的主要成分是水,约占总成分的98%到99%,其余物质为氯化钠,极少量的尿素、氨和其他盐类
  • 鲁道夫·朱利安尼鲁道夫·威廉·路易斯·“鲁迪”·朱利安尼,KBE(英语:Rudolph William Louis "Rudy" Giuliani,1944年5月28日-)是美国律师、检察官、商人及共和党的美国政治人物,出身于纽约州。朱
  • 赫鲁晓夫解冻苏联主题赫鲁晓夫解冻(俄语:хрущёвская о́ттепель,转写:khrushchovskaya ottepel)指因苏共中央第一书记尼基塔·赫鲁晓夫在1950年代中期到1960年代实行去斯大
  • 2019冠状病毒病洪都拉斯疫情2019冠状病毒病洪都拉斯疫情,介绍在2019新型冠状病毒疫情中,在洪都拉斯发生的情况。2020年3月10日,洪都拉斯首次确诊2例新冠肺炎感染病例。一例为42岁洪都拉斯孕妇,4日从西班牙