使多个对象都有机会处理请求,从而避免了请求的发送者和接收者指间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
- 责任链模式的优点
责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提高系统的灵活性。
责任链模式的缺点
- 性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题;
- 调试不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
责任链模式的注意事项
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。
<?php
/**
* 责任链模式
*/
namespace pattern;
abstract class Handler {
const LEVEL_ONE = '1';
const LEVEL_TWO = '2';
const LEVEL_THREE = '3';
protected $next_handler = null;
public function setNext(Handler $handler) {
$this->next_handler = $handler;
}
public function handleRequest(Request $request) {
if ($request->getRequestLevel() === $this->getLevel()) {
$this->operate();
} else {
if ($this->next_handler === null) {
echo 'no handler' . PHP_EOL;
} else {
$this->next_handler->handleRequest($request);
}
}
}
abstract public function getLevel();
abstract public function operate();
}
final class ConcreteOne extends Handler {
public function getLevel() {
return parent::LEVEL_ONE;
}
public function operate() {
echo 'One is operating...' . PHP_EOL;
}
}
final class ConcreteTwo extends Handler {
public function getLevel() {
return parent::LEVEL_TWO;
}
public function operate() {
echo 'Two is operating...' . PHP_EOL;
}
}
final class ConcreteThree extends Handler {
public function getLevel() {
return parent::LEVEL_THREE;
}
public function operate() {
echo 'Three is operating...' . PHP_EOL;
}
}
class Request {
private $_request_level = null;
public function __construct() {
$arr = array(
Handler::LEVEL_ONE,
Handler::LEVEL_THREE,
Handler::LEVEL_TWO,
null
);
$this->_request_level = $arr[array_rand($arr, 1)];
}
public function getRequestLevel() {
return $this->_request_level;
}
}
$one = new ConcreteOne();
$two = new ConcreteTwo();
$three = new ConcreteThree();
$one->setNext($two);
$two->setNext($three);
$response = $one->handleRequest(new Request());

272

被折叠的 条评论
为什么被折叠?



