责任链模式

✍ dations ◷ 2025-10-11 07:18:49 #软件设计模式

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

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

相关

  • 阿尔文·普兰丁格阿尔文·卡尔·普兰丁格(英语:Alvin Carl Plantinga,1932年11月15日-),美国当代著名的基督教哲学家,现任圣母大学John A.O'Brien讲席教授。他的研究领域包括基督教神学、认识论和形
  • 人民院Government (355) National Democratic Alliance (355)Opposition (188) United Progressive Alliance (93)Others (95)Vacant (2)人民院(印地语:लोक सभा;英语:House of t
  • 太湖猪太湖猪是家猪的品种之一,起源于中国长江下游太湖流域一带。形体庞大,色黑。双耳下垂且面部带有褶皱。有多个品系,有学者视其为不同的猪种。太湖猪对疾病有高抵抗力,而又有较强的
  • 人工阴道 (工具)人工阴道是一种模仿女性阴道的人造物品工具,可以提供类似于性交的快感,人工阴道可以用在医学用途,用于收集男性精液,或者解决性需求时作为性玩具使用。也有模仿动物,如雌马的人工
  • LGBT抚养议题反对相关LGBT抚养是指的是LGBT族群(男同性恋、女同性恋、双性恋和跨性别)从伴侣关系走向包括一个或多个抚养对象的家庭关系的过程。根据社会的发展和科学的进步 ,目前抚养
  • 费米辉光费米辉光是颗粒发出的强烈紫外线,通常是来自太阳系弓形震波的氢。是来自恒星和太阳的光进入日球层顶(heliopause)和星际物质之间的区域时,经历费米加速,在过渡区蹦来蹦去好几回,通
  • 亨利六世 (英格兰)亨利六世(Henry VI,1421年12月6日-1471年5月21日)兰开斯特王朝的最后一位英格兰国王(1422年—1461年;1470年—1471年)。由于他的软弱,英格兰在亨利五世时代取得的丰硕战果丧失殆尽,且
  • 饮 (中医)饮是中医诊断学上的名词,指体内的液体运行输布失常,因而停留在体内某处所形成的病理产物。“饮”与痰性质相似,同为津液代谢障碍之病变,但状态不同,“痰”较为混浊粘稠而“饮”较
  • 周廷欣周廷欣(1964年-),原郑州市公安局原副局长。1993年从武警部队转入郑州市公安系统工作,2008年2月开始在郑州市公安局工作,2010年3月升任郑州市公安局党委委员、副局长,工作职责为分管
  • ㅛ是朝鲜语谚文中的一个元音字母,在韩国的谚文字母表中排序第20位,在元音字母中排序第6。该字母的名称为“요”。ㅛ是一个双元音,由硬颚近音半元音.mw-parser-output .IPA{font