五、责任链模式
5.1什么是责任链模式
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,
并沿着这条链传递该请求,直到有对象处理它为止
5.2怎么实现责任链模式
责任链模式的核心在“链”上,“链”是由多个处理者 Handler 组成的
抽象的 Handler 类:定义抽象方法,提供注册下一个 Handler 的接口
具体的 Handler 类:实现抽象类方法,注册自己能处理的事件级别
事件类:定义自己的事件级别
<?php
class Request
{
private int $level = 1;
public function __construct(int $level)
{
$this->level = $level;
}
public function getLevel(): int
{
return $this->level;
}
}
abstract class Handler
{
private Handler $nextHandler;
public function handleMessage(Request $request): bool
{
$response = false;
if ($this->getHandlerLevel() == $request->getLevel()) {
$response = $this->echo();
} else {
if (isset($this->nextHandler)) {
$response = $this->nextHandler->handleMessage($request);
}
}
return $response;
}
public function setNext(Handler $handler)
{
$this->nextHandler = $handler;
}
protected abstract function getHandlerLevel(): int;
protected abstract function echo(): bool;
}
class Handler1 extends Handler
{
protected function getHandlerLevel(): int
{
return 1;
}
protected function echo(): bool
{
echo "handler1 deal\n";
return true;
}
}
class Handler2 extends Handler
{
protected function getHandlerLevel(): int
{
return 2;
}
protected function echo(): bool
{
echo "handler2 deal\n";
return true;
}
}
class Handler3 extends Handler
{
protected function getHandlerLevel(): int
{
return 3;
}
protected function echo(): bool
{
echo "handler3 deal\n";
return true;
}
}
$handler1 = new Handler1();
$handler2 = new Handler2();
$handler3 = new Handler3();
$handler1->setNext($handler2);
$handler2->setNext($handler3);
echo "start deal request2\n";
$request2 = new Request(2);
$handler1->handleMessage($request2);
echo "end deal request2\n\n\n";
echo "start deal request4\n";
$request4 = new Request(4);
if (!$handler1->handleMessage($request4)) {
echo "request4 not be processed\n";
}
echo "end deal request2\n";
5.3责任链模式优点是什么
链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,
两者解耦,提高系统的灵活性
5.4责任链模式缺点是什么
责任链有两个非常显著的缺点:
-
性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题
-
调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂
5.5责任链模式注意事项
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,
在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能