浅谈PHP设计模式的责任链模式
简介:
责任链模式又叫做职责链模式,是属于行为型的一种。
责任链模式分为两种:
第一种像工厂流水线,目的就让每一个环节都进行处理。
第二种像层层审批,如果其中一个对象无法处理,调用下一个对象来进行处理,如果一旦能处理,链式就此停止,以此类推,第二种为了程序的健壮性,至少得需要一个兜底的模块,防止穿透责任链。
适用场景:
对请求参数进行逐层过滤,用于框架的中间件的开发场景(Laravel Middleware)。日志框架,每个链元素自主决定如何处理日志消息。
优点:
简化了调用端的操作,调用端无须关心请求的处理细节和请求的传递过程,因为请求会自动进行传递到整条链路。
缺点:
期间实例化的很多的对象,其实完全可以用普通的if去替代。
调试不方便。
代码(内部关联)
//责任链模式好像没有固定的实现方案,只是一种思想,所以实现一个展示活跃类型的的功能。这种方式方便调用端处理,但是依赖在类的内部,不利于后期维护。
//也可以优化调用和实例化在类的外部进行,缺点是会增加调用端的复杂度,有点是可控度更高。到底如何实现这要看应用场景,但是链式的思想是一致的。
class shortTerm {
private function next($time) {
return (new OneDay())->show($time);
}
public function show($time) {
if($time <= 3) {
return '刚刚活跃';
}
return $this->next($time);
}
}
class OneDay {
private function next($time) {
return (new ThreeDay())->show($time);
}
public function show($time) {
if($time <= 24) {
return '当天活跃';
}
return $this->next($time);
}
}
class ThreeDay {
private function next($time) {
return (new SevenDay())->show($time);
}
public function show($time) {
if($time <= 72) {
return '三日内活跃';
}
return $this->next($time);
}
}
class SevenDay {
public function show($time) {
return '不活跃';
}
}
//调用端
echo (new shortTerm())->show(600);
代码(外部关联)
- 为什么使用抽象类,因为抽象类既能约束规范,也能像父类一样共享数据,并且比接口功能多,可以实现自定义的逻辑。
- 以下代码可以总结出责任链模式的固定的套路:自身的逻辑+链路往下走的方向。
abstract class UserActivation {
//指定一个存放下一个链式对象的容器
public $next;
//设置让容器存下一个链式调用的对象
public function next(UserActivation $next) {
$this->next = $next;
}
//定义一个抽象方法,用于逻辑实现。
abstract public function handle($request);
}
class ShortTerm extends UserActivation {
public function handle($request) {
if($request <= 3) {
return '刚刚活跃';
}
return $this->next->handle($request);
}
}
class OneDay extends UserActivation {
public function handle($request) {
if($request <= 24) {
return '当天活跃';
}
return $this->next->handle($request);
}
}
class ThreeDay extends UserActivation {
public function handle($request) {
if($request <= 72) {
return '三日内活跃';
}
return $this->next->handle($request);
}
}
class SevenDay extends UserActivation {
public function handle($request) {
return '不活跃';
}
}
//调用端=============================================
//整理好随时可能要用到的对象
$short_term = new ShortTerm();
$one_day = new OneDay();
$three_day = new ThreeDay();
$seven_day = new SevenDay();
//确认好链式往下走的方向。
$short_term->next($one_day);
$one_day->next($three_day);
$three_day->next($seven_day);
//创建任务逐个传递
echo $short_term->handle(80);