责任链模式

✍ dations ◷ 2024-12-22 18:50:23 #软件设计模式

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

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

相关

  • 诺曼底王朝本条目是分类中的文章诺曼底王朝(1066年-1135年;英语:House of Normandy)是英格兰的一个王朝,共有四位诺曼底家族的国王先后统治英格兰,统治时间由征服王威廉之后的1066年开始,直至
  • 诺福克岛诺福克岛(英语:Norfolk Island)是澳大利亚的一个岛屿(拉脱维亚语:Norfolka (sala)),与紧邻的菲利普岛和尼皮恩岛共同组成一个澳大利亚海外领地。面积约34.6平方公里。人口1748人(201
  • 乳头凹陷乳头凹陷也称为乳头内陷,是指乳头凹陷,未突出乳房的情形。凹陷的乳头若受到刺激,也可能会暂时突出。女性和男性都可能有乳头凹陷的症状。最常见的病因包括:大约10-20%的女性出生
  • 气球炸弹气球炸弹(英文:Fire balloons/Balloon bombs,日文:風船爆弾),是日本在二战时期使用的一种武器,为气象学家荒川秀俊(日语:荒川秀俊)于1942年设计。荒川秀俊也因此被远东国际军事法庭裁
  • 南加州都会铁路南加州都会铁道(Metrolink),又译:南加州通勤铁路,大都会通勤铁路,或南加州城铁(标识:SCAX)是一个为南加州洛杉矶及周边地区提供通勤铁路服务的系统,目前该系统有7条线路以及55个火车站
  • 沙欣珍妮·沙欣(英语:Jeanne Shaheen(原名辛西娅·珍妮·鲍尔斯(英语:Cynthia Jeanne Bowers));1947年1月28日-),是一位美国民主党政治人物,自2009年成为新罕布什尔州历史上首位女性联邦参议
  • “不让任何孩子落后”法案有教无类法案(No Child Left Behind Act of 2001,Public Law 107-110),又译为不让任何孩子落后法案,简称为NCLB,是2002年1月8日由美国总统乔治·沃克·布希签署的一项美国联邦法律
  • 古希腊音乐古希腊音乐是古希腊人生活中重要的一部分,它存在宗教乐、民乐等多种形式,在皮西安竞技会、奥林匹克运动会和剧院里音乐也是重要元素之一,现在古希腊音乐仍可从一些保留下来的乐
  • 有你真好 (电影)《有你真好》(The Way Home)是一部韩国剧情片。母亲把7岁儿子相宇送至偏僻乡下的外婆家,作为单身母亲的妈妈为了方便找工作暂时把相宇留在那里,由又老又哑的外婆暂时照顾。相宇
  • 佩克洛峰坐标:45°37′56″N 06°13′52″E / 45.63222°N 6.23111°E / 45.63222; 6.23111佩克洛峰(法语:Mont Pécloz),是法国的山峰,位于该国东部,由萨瓦省负责管辖,处于首都巴黎东南面50