职责链模式

作者: wudanyang | 来源:发表于2018-03-06 13:27 被阅读17次

什么是职责链模式

在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

为什么要使用

解耦了请求者与处理者。

常见的职责链模式场景

  1. 语言的异常机制,一个 try 对应多个 catch
  2. 请假审批
  3. 轮流出牌

类型

行为型模式

参与者

  1. Client 发出请求,构造职责链。
  2. Handler 抽象的处理类
    • 定义一个请求处理接口
    • 定义链上的下一个接口
  3. 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();

请假人小明,天数:3,理由:旅游
审批人:主管
请假人小红,天数:13,理由:看花灯
审批人:总经理
请假人:小亮,天数:8,理由:看病
审批人:经理

相关文章

网友评论

    本文标题:职责链模式

    本文链接:https://www.haomeiwen.com/subject/sqqzxftx.html