欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

职责分明的责任链模式(Chain of Responsibility Pattern)

程序员文章站 2022-05-04 08:43:48
...

中国自古有重男轻女的观念,在古代,未婚女子要想出去逛街都要经过父亲的同意,而有丈夫的则要请示丈夫,如果丈夫去世了,有儿子的还得请示儿子,这就是所谓的“三从”。果然很苦逼!我们用程序来模拟一下这个过程:

<?php
interface IWomen{
	public function gettype();
	public function getRequest();
}


class Women implements IWomen{
	/*
	* 1--未出嫁
	* 2--出嫁
	* 3--夫死
	 */
	private $type = 0;
	private $request = '';
	public function __construct( $type, $request ) {
		$this->type = $type;
		$this->request = $request;
	}
	public function gettype() {
		return $this->type;
	}
	public function getRequest() {
		return $this->request;
	}
}

interface IHandler{
	public function handleMessage( $women );
}


class Father implements IHandler{
	public function handleMessage( $women ) {
		echo "女儿的请求是".$women->getRequest()."\n";
		echo "父亲的答复是:同意!\n";
	}
}
class Husband implements IHandler{
	public function handleMessage( $women ) {
		echo "妻子的请求是".$women->getRequest()."\n";
		echo "丈夫的答复是:同意!\n";
	}
}
class Son implements IHandler{
	public function handleMessage( $women ) {
		echo "母亲的请求是".$women->getRequest()."\n";
		echo "儿子的答复是:同意!\n";
	}
}

for($type = 1;$type<=3;$type++):
	$women = new Women($type,'逛街');
	switch ($type) {
		case '1':
			$handler = new Father();
			break;
		case '2':
			$handler = new Husband();
			break;
		default:
			$handler = new Son();
			break;
	}
	$handler->handleMessage($women);
endfor;
?>
运行结果:
女儿的请求是逛街
父亲的答复是:同意!
妻子的请求是逛街
丈夫的答复是:同意!
母亲的请求是逛街
儿子的答复是:同意!
[Finished in 0.1s]

 实现很简单,代码也比较容易,但是这样的设计有几个问题:

1、职责界定不清晰

对女儿的提出的请示,应该在父亲类中做出决定,父亲有责任、有义务处理女儿的请求。因此Father类应该是知道女儿的请求自己处理,而不是在Client中进行组装出来,也就是说原本应该是父亲这个类做的事情抛给了其他地方进行处理。

2、代码臃肿

在client中写了swith判断条件,而且能随着能处理该类型的请示人员越多,switch判断就越多,这样倒置可读性大大下降。

3、耦合过重

client根据women的type来决定使用IHandler的哪个实现类来处理请求。但如果IHandler的实现类继续扩展呢,那就得修改client,与开闭原则违背了!

4、异常情况欠考虑

如果妻子是个不懂三从的人,她已有丈夫却向父亲去请示,那父亲应该如何处理?上面的程序完全没有考虑这种异常情况!

那该如何改进?不难发现,整个请示的过程可以构成一条“链”。“链头“是父亲,无论女子是否已结婚全都请示父亲,父亲得知女儿结婚了,就传给女儿的丈夫,丈夫如果过世了,再传给儿子。看下类图:

职责分明的责任链模式(Chain of Responsibility Pattern)
            
    
    博客分类: 设计模式 设计模式责任链模式php 
实现代码如下:

<?php
interface IWomen{
	public function gettype();
	public function getRequest();
}


class Women implements IWomen{
	/*
	* 1--未出嫁
	* 2--出嫁
	* 3--夫死
	 */
	private $type = 0;
	private $request = '';
	public function __construct( $type, $request ) {
		$this->type = $type;
		$this->request = $request;
	}
	public function gettype() {
		return $this->type;
	}
	public function getRequest() {
		return $this->request;
	}
}

abstract class IHandler {
	const FATHER_LEVEL_REQUEST = 1;
	const HUSBAND_LEVEL_REQUEST = 2;
	const SON_LEVEL_REQUEST = 3;
	private $level = 0;
	private $nextHandler;
	protected function __construct( $level ) {
		$this->level = $level;
	}
	final public function handleMessage( $women ) {
		if ( $women->getType() == $this->level )
			$this->reponse( $women );//这里回调子类方法
		else {
			if ( $this->nextHandler != NULL )
				$this->nextHandler->handleMessage( $women );
			else
				echo "没地方请示了,按不同意处理!\n";
		}
	}
	public function setNext( $handler ) {
		$this->nextHandler = $handler;
	}
	abstract protected function reponse( $women );
}


class Father extends IHandler{
	public function __construct() {
		parent::__construct( parent::FATHER_LEVEL_REQUEST );
	}
	public function reponse( $women ) {
		echo "女儿的请求是".$women->getRequest()."\n";
		echo "父亲的答复是:同意!\n";
	}
}
class Husband extends IHandler{
	public function __construct() {
		parent::__construct( parent::HUSBAND_LEVEL_REQUEST );
	}
	public function reponse( $women ) {
		echo "妻子的请求是".$women->getRequest()."\n";
		echo "丈夫的答复是:同意!\n";
	}
}
class Son extends IHandler{
	public function __construct() {
		parent::__construct( parent::SON_LEVEL_REQUEST );
	}
	public function reponse( $women ) {
		echo "母亲的请求是".$women->getRequest()."\n";
		echo "儿子的答复是:同意!\n";
	}
}

for($i=0;$i<=3;$i++){
	$women = new Women($i,'逛街');
	$father = new Father();
	$husband = new Husband();
	$son = new Son();
	$father->setNext($husband);
	$husband->setNext($son);
	$father->handleMessage($women);
}
?>
运行结果:
没地方请示了,按不同意处理!
女儿的请求是逛街
父亲的答复是:同意!
妻子的请求是逛街
丈夫的答复是:同意!
母亲的请求是逛街
儿子的答复是:同意!
[Finished in 0.1s]

 例子中不难发现,其实还用到了模板方法模式

 

 

责任链模式的定义

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

 

 

责任链模式的优点

最为显著的优点就是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提高系统的灵活性。

 

 

责任链模式的缺点

一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个问题。二是调试不是很方便,特别是链条比较长的,环节比较多的时候,由于采用了类似递归的方式 ,调试的时候逻辑可能比较复杂。

 

  • 职责分明的责任链模式(Chain of Responsibility Pattern)
            
    
    博客分类: 设计模式 设计模式责任链模式php 
  • 大小: 7.1 KB