官方定义
将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求,将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
通俗定义
说到底就是 多个处理器类对同一个接受对象进行处理。按照从上倒下依次去执行。比如在核酸检测期间,为了保证看病人员的中风险范围的筛选。医院会有一条通道,我们经过这条通道过程中,需要一层一层的扫码,只有通过最后一步检测的才能看病。并且如果我们需要多增加一条检测,只需要在同道中,多一扫码(类似代码中的处理类)。
简单实现
<?php
// 病人类
class Patient
{
// 名字
public $name;
// 体温
public $temperature;
// 途径地区
public $routeArea;
public function __construct(string $name, string $temperature, string $routeArea)
{
$this->name = $name;
$this->temperature = $temperature;
$this->routeArea = $routeArea;
}
}
// 检查抽象类
abstract class Inspect
{
public $inspect;
public function setSuccessor(Inspect $inspect)
{
$this->inspect = $inspect;
}
public abstract function handle(Patient $staff);
}
// 途径地区检查
class RouteAreaRule extends Inspect
{
/**
* @param Patient $staff
*/
public function handle(Patient $staff)
{
if ($staff->routeArea == '广州') {
echo '在广州不能看病';
} else {
$this->inspect->handle($staff);
}
}
}
// 体温检查
class TemperatureRule extends Inspect
{
/**
* @param Patient $staff
*/
public function handle(Patient $staff)
{
if ($staff->temperature > '37') {
echo '体温大于 37 度 不能进去看病';
} else {
$this->inspect->handle($staff);
}
}
}
$staff = (new Patient('monkey', '37.5', '广州'));
$routeAreaRule = new RouteAreaRule();
$temperatureRule = new TemperatureRule();
$routeAreaRule->setSuccessor($temperatureRule);
$routeAreaRule->handle($staff);
应用场景
- 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。
- 可动态指定一组对象处理请求,或添加新的处理者。
- 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。
- 对于HTTP请求做中间件处理时,可以使用职责链模式。
- 常用来开发框架的过滤器和拦截器。
优点
- 灵活易扩展:如果要新增一个过滤类,则只需要新建一个处理类就行了。
缺点
- 对新手不友好,学习成本高。
- 增加系统的复杂度。
- 如果设计不好,可能增加维护的难度。调试时不太方便。