什么是职责链模式
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
为什么要使用
解耦了请求者与处理者。
常见的职责链模式场景
语言的异常机制,一个 try 对应多个 catch
请假审批
轮流出牌
类型
行为型模式
参与者
Client 发出请求,构造职责链。
Handler 抽象的处理类
定义一个请求处理接口
定义链上的下一个接口
ConcreteHandler 具体的处理类
例子
<?php
/**
* 请假审批
*/
/**
* 请假类
* Class LeaveRequest
*/
class LeaveRequest {
public $empName;
public $leaveDays;
public $reason;
public function __construct($empName, $leaveDays, $reason)
{
$this->empName = $empName;
$this->leaveDays = $leaveDays;
$this->reason = $reason;
}
}
/**
* 责任人
* Class Leader
*/
abstract class Leader {
protected $name;
/**
* @var Leader
*/
protected $nextLeader;
public function __construct($name)
{
$this->name = $name;
}
public function setNextLeader(Leader $nextLeader)
{
$this->nextLeader = $nextLeader;
}
public abstract function handleRequest(LeaveRequest $leaveRequest);
}
/**
* 主管
* Class Direct
*/
class Director extends Leader {
public function __construct($name)
{
parent::__construct($name);
}
/**
* 主管能批准三天以下的请假
* @param LeaveRequest $leaveRequest
*/
public function handleRequest(LeaveRequest $leaveRequest)
{
if ($leaveRequest->leaveDays <= 3) {
echo '请假人'.$leaveRequest->empName.',天数:'.$leaveRequest->leaveDays.',理由:'.$leaveRequest->reason.PHP_EOL;
echo '审批人:'.$this->name.PHP_EOL;
} else {
if (!empty($this->nextLeader)) {
$this->nextLeader->handleRequest($leaveRequest);
}
}
}
}
/**
* 经理
* Class Manager
*/
class Manager extends Leader {
public function __construct($name)
{
parent::__construct($name);
}
/**
* 经理批准三天以上十天以下的请假
* @param LeaveRequest $leaveRequest
*/
public function handleRequest(LeaveRequest $leaveRequest)
{
if ($leaveRequest->leaveDays <= 10) {
echo '请假人:'.$leaveRequest->empName.',天数:'.$leaveRequest->leaveDays.',理由:'.$leaveRequest->reason.PHP_EOL;
echo '审批人:'.$this->name.PHP_EOL;
} else {
if (!empty($this->nextLeader)) {
$this->nextLeader->handleRequest($leaveRequest);
}
}
}
}
/**
* 总经理
* Class GeneralManager
*/
class GeneralManager extends Leader {
public function __construct($name)
{
parent::__construct($name);
}
/**
* 总经理批准十天以上的请假
* @param LeaveRequest $leaveRequest
*/
public function handleRequest(LeaveRequest $leaveRequest)
{
echo '请假人'.$leaveRequest->empName.',天数:'.$leaveRequest->leaveDays.',理由:'.$leaveRequest->reason.PHP_EOL;
echo '审批人:'.$this->name.PHP_EOL;
}
}
class Client {
public function run()
{
// 构建责任链处理者
$director = new Director('主管');
$manager = new Manager('经理');
$generalManager = new GeneralManager('总经理');
// 设置各个责任链的关系
$director->setNextLeader($manager);
$manager->setNextLeader($generalManager);
// 请假
$request = new LeaveRequest('小明', 3, '旅游');
$director->handleRequest($request);
$request = new LeaveRequest('小红', 13, '看花灯');
$director->handleRequest($request);
$request = new LeaveRequest('小亮', 8, '看病');
$director->handleRequest($request);
}
}
$client = new Client();
$client->run(); |