• B5:责任链模式 Chain Of Responsibility


    使多个对象都有机会处理处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着该链处理请求,直到有一个对象能够处理它为止.

    相当于switch/case,在客户端指定了每一链的下一链.

    UML

    示例代码:

    abstract class Handle
    {
        protected $nextHandle;
    
        public function setNextHandle(Handle $handle)
        {
            $this->nextHandle = $handle;
        }
    
        abstract public function handleRequest($level);
    }
    
    class Handle1 extends Handle
    {
        public function handleRequest($level)
        {
            if ($level > 0 && $level < 10) {
                echo 'Handle1 处理了';
            } elseif(!is_null($this->nextHandle)) {
                $this->nextHandle->handleRequest($level);
            }
        }
    }
    
    class Handle2 extends Handle
    {
        public function handleRequest($level)
        {
            if ($level > 10 && $level < 100) {
                echo 'Handle2 处理了';
            } elseif(!is_null($this->nextHandle)) {
                $this->nextHandle->handleRequest($level);
            }
        }
    }
    
    class Handle3 extends Handle
    {
        public function handleRequest($level)
        {
            if ($level > 100 && $level < 1000) {
                echo 'Handle3 处理了';
            } elseif(!is_null($this->nextHandle)) {
                $this->nextHandle->handleRequest($level);
            }
        }
    }
    
    $handle1 = new Handle1();
    $handle2 = new Handle2();
    $handle3 = new Handle3();
    $handle1->setNextHandle($handle2);
    $handle2->setNextHandle($handle3);
    
    $handle1->handleRequest(600);
    

      

    这个手动设置下一处理者,还是有点不方便.有时候设置出错,容易导致死循环,我们改进一下.

    示例代码:

    abstract class Handle
    {
        abstract public function handleRequest($level);
    }
    
    class Handle1 extends Handle
    {
        public function handleRequest($level)
        {
            if ($level > 0 && $level < 10) {
                echo 'Handle1 处理了';
                return true;
            }
        }
    }
    
    class Handle2 extends Handle
    {
        public function handleRequest($level)
        {
            if ($level > 10 && $level < 100) {
                echo 'Handle2 处理了';
                return true;
            }
        }
    }
    
    class Handle3 extends Handle
    {
        public function handleRequest($level)
        {
            if ($level > 100 && $level < 1000) {
                echo 'Handle3 处理了';
                return true;
            }
        }
    }
    
    class Context
    {
        protected $chains = [];
    
        public function addHandle(Handle $handle)
        {
            $this->chains[] = $handle;
        }
    
        public function handleRequest($level)
        {
            foreach ($this->chains as $handler) {
                if ($handler->handleRequest($level)) {
                    break;
                }
            }
        }
    }
    
    $context = new Context();
    $context->addHandle(new Handle1());
    $context->addHandle(new Handle2());
    $context->addHandle(new Handle3());
    
    $context->handleRequest(600);
    

      

    我们将链的设置交给Context,Context维护了一个数组来保存设置的处理者.context中的handleRequest方法,循环从数组中读取并处理.在每个处理者类中,我们让其如果有处理,就返回true,在foreach循环中跳出循环,防止无用的循环继续下去.

    当然有时候我们需要职责链的每个处理者挨个处理请求,也可以使用这种方法.

  • 相关阅读:
    CAM350中DFM检验
    减少VMware中虚拟系统占用的内存资源
    嵌入式系统开发学习如何起步、如何深入
    GNOME3介绍与使用技巧
    局域网网络相关的问题
    开篇:讲讲peopleeditor遇到的问题
    WSDL
    常用shell命令(持续更新)
    X86寄存器及指令介绍
    float型与零值比较的语句;float型与float型如何判断相等
  • 原文地址:https://www.cnblogs.com/itfenqing/p/7791482.html
Copyright © 2020-2023  润新知