PHP 责任链模式

使多个对象都有机会处理请求,从而避免了请求的发送者和接收者指间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

  • 责任链模式的优点

责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提高系统的灵活性。

  • 责任链模式的缺点

    1. 性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题;
    2. 调试不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
  • 责任链模式的注意事项

链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。

<?php
/**
 * 责任链模式
 */
namespace pattern;

abstract class Handler {
    const LEVEL_ONE = '1';
    const LEVEL_TWO = '2';
    const LEVEL_THREE = '3';

    protected $next_handler = null;

    public function setNext(Handler $handler) {
        $this->next_handler = $handler;
    }
    public function handleRequest(Request $request) {
        if ($request->getRequestLevel() === $this->getLevel()) {
            $this->operate();
        } else {
            if ($this->next_handler === null) {
                echo 'no handler' . PHP_EOL;
            } else {
                $this->next_handler->handleRequest($request);
            }
        }
    }
    abstract public function getLevel();
    abstract public function operate();
}

final class ConcreteOne extends Handler {
    public function getLevel() {
        return parent::LEVEL_ONE;
    }
    public function operate() {
        echo 'One is operating...' . PHP_EOL;
    }
}
final class ConcreteTwo extends Handler {
    public function getLevel() {
        return parent::LEVEL_TWO;
    }
    public function operate() {
        echo 'Two is operating...' . PHP_EOL;
    }
}
final class ConcreteThree extends Handler {
    public function getLevel() {
        return parent::LEVEL_THREE;
    }
    public function operate() {
        echo 'Three is operating...' . PHP_EOL;
    }
}

class Request {
    private $_request_level = null;
    public function __construct() {
        $arr = array(
            Handler::LEVEL_ONE,
            Handler::LEVEL_THREE,
            Handler::LEVEL_TWO,
            null
        );
        $this->_request_level = $arr[array_rand($arr, 1)];
    }
    public function getRequestLevel() {
        return $this->_request_level;
    }
}

$one = new ConcreteOne();
$two = new ConcreteTwo();
$three = new ConcreteThree();
$one->setNext($two);
$two->setNext($three);

$response = $one->handleRequest(new Request());
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值