简介:

责任链模式又叫做职责链模式,是属于行为型的一种。
责任链模式分为两种:
第一种像工厂流水线,目的就让每一个环节都进行处理。
第二种像层层审批,如果其中一个对象无法处理,调用下一个对象来进行处理,如果一旦能处理,链式就此停止,以此类推,第二种为了程序的健壮性,至少得需要一个兜底的模块,防止穿透责任链。

适用场景:

对请求参数进行逐层过滤,用于框架的中间件的开发场景(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);
代码(外部关联)
  1. 为什么使用抽象类,因为抽象类既能约束规范,也能像父类一样共享数据,并且比接口功能多,可以实现自定义的逻辑。
  2. 以下代码可以总结出责任链模式的固定的套路:自身的逻辑+链路往下走的方向。
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);