zoukankan      html  css  js  c++  java
  • PHP设计模式—职责链模式

    定义:

    职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

     

    结构:

    • Handler:抽象类,定义一个处理请示的接口。
    • ConcreteHandler:具体处理者类,处理它所负责的请求,可访问它的后继者,如果可以处理该请求,就处理之,否则就将请求转发给它的后继者。
    • Client:客户端代码。

     

    代码实例:

    /**
     * 抽象类,定义一个处理请示的接口
     * Class Handler
     */
    abstract class Handler
    {
        /**
         * 存放下一个处理对象
         * @var
         */
        protected $nextHandler;
    
    
        /**
         * 设置下一个处理对象
         * @param Handler $handler
         */
        public function setNextHandler(Handler $handler)
        {
            $this->nextHandler = $handler;
        }
    
    
        /**
         * 抽象方法,由具体处理者类实现
         * @param $request
         * @return mixed
         */
        abstract public function handlerRequest($request);
    }
    
    
    /**
     * 具体处理者类
     * Class ConcreteHandler1
     */
    class ConcreteHandler1 extends Handler
    {
        /**
         * 具体处理逻辑
         * @param $request
         * @return mixed|void
         */
        public function handlerRequest($request)
        {
            // TODO: Implement handlerRequest() method.
            if ($request >= 0 && $request < 10) {
                // ConcreteHandler1可以处理0~10的请求
                echo 'ConcreteHandler1处理这个请求<br>';
            } elseif ($this->nextHandler) {
                // 请求转发给下一个处理对象
                $this->nextHandler->handlerRequest($request);
            } else {
                echo 'ConcreteHandler1处理异常<br>';
            }
        }
    }
    
    
    /**
     * 具体处理者类
     * Class ConcreteHandler2
     */
    class ConcreteHandler2 extends Handler
    {
        /**
         * 具体处理逻辑
         * @param $request
         * @return mixed|void
         */
        public function handlerRequest($request)
        {
            // TODO: Implement handlerRequest() method.
            if ($request >= 10 && $request < 20) {
                // ConcreteHandler2可以处理10~20的请求
                echo 'ConcreteHandler2处理这个请求<br>';
            } elseif ($this->nextHandler) {
                // 请求转发给下一个处理对象
                $this->nextHandler->handlerRequest($request);
            } else {
                echo 'ConcreteHandler2处理异常<br>';
            }
        }
    }
    
    
    /**
     * 具体处理者类
     * Class ConcreteHandler3
     */
    class ConcreteHandler3 extends Handler
    {
        /**
         * 具体处理逻辑
         * @param $request
         * @return mixed|void
         */
        public function handlerRequest($request)
        {
            // TODO: Implement handlerRequest() method.
            if ($request >= 20) {
                // ConcreteHandler3可以处理大于20的请求
                echo 'ConcreteHandler3处理这个请求<br>';
            } elseif ($this->nextHandler) {
                // 请求转发给下一个处理对象
                $this->nextHandler->handlerRequest($request);
            } else {
                echo 'ConcreteHandler3处理异常<br>';
            }
        }
    }
    
    
    // 客户端代码
    // 实例化处理者
    $handler1 = new ConcreteHandler1();
    $handler2 = new ConcreteHandler2();
    $handler3 = new ConcreteHandler3();
    
    // 职责链组装,定义链的结构,设置职责链上家与下家
    $handler1->setNextHandler($handler2);
    $handler2->setNextHandler($handler3);
    
    // 调用请求
    $handler1->handlerRequest(5);
    $handler1->handlerRequest(15);
    $handler1->handlerRequest(35);
    
    
    // 结果
    ConcreteHandler1处理这个请求
    ConcreteHandler2处理这个请求
    ConcreteHandler3处理这个请求

     

    总结:

    • 当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。
    • 职责链模式中接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。所以职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用,这大大降低了耦合度。
    • 由于是在客户端来定义链的结构,可以随时地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。
    • 需要注意的是,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,因此需要事先考虑全面。
  • 相关阅读:
    1105 Spiral Matrix (25分)(蛇形填数)
    1104 Sum of Number Segments (20分)(long double)
    1026 Table Tennis (30分)(模拟)
    1091 Acute Stroke (30分)(bfs,连通块个数统计)
    1095 Cars on Campus (30分)(排序)
    1098 Insertion or Heap Sort (25分)(堆排序和插入排序)
    堆以及堆排序详解
    1089 Insert or Merge (25分)
    1088 Rational Arithmetic (20分)(模拟)
    1086 Tree Traversals Again (25分)(树的重构与遍历)
  • 原文地址:https://www.cnblogs.com/woods1815/p/15063433.html
Copyright © 2011-2022 走看看