Home  >  Article  >  Backend Development  >  Understand the responsibility chain model of PHP design pattern in one article

Understand the responsibility chain model of PHP design pattern in one article

齐天大圣
齐天大圣Original
2020-08-08 08:20:111954browse

The chain of responsibility model is a behavioral design model. The request is sent along the processor chain. After receiving the request, each processor can process the request or pass the request to the next processor on the chain. . Each processor on the chain has its own processing responsibilities, so it is called the chain of responsibility model.

Scenario

Suppose there is currently a system, and now we want to restrict access to the system. The first is login verification. All requests to this system need to be logged in to obtain.

After a while, the boss felt that an anti-crawler program should be added. The boss has the biggest task. You immediately add the anti-crawler function to the original verification code. At present, the login verification and anti-crawler verification are not very complicated. But after a few days, the boss felt that current limit verification should be added... A few days later, the boss...

The code blocks related to verification have become bloated, and the code has become difficult to read and maintain. At this time, if we use the chain of responsibility model to rewrite the verification function system, it will look like the following:

Understand the responsibility chain model of PHP design pattern in one article

Through the chain of responsibility model, multiple processors There is an opportunity to process the request. Dividing the original module into multiple processors for processing conforms to the single responsibility principle and greatly improves the readability of the code. In addition, it is very easy to expand. When new verification functions are needed, just add a new processor, which complies with the opening and closing principle.

Chain of Responsibility Pattern Structure

Let’s complete the code of a chain of responsibility pattern structure. The function of each handler is very simple, it is to handle the request and then set up the next request handler. The following is a sample code:

abstract class AHandler
{
    protected $nextHandler = null;
    
    public function setNext (AHandler $handler)
    {
        $this->nextHandler = $handler;
    }
    
    abstract public function handler ();
}
class Handler1 extends AHandler
{
    public function handler()
    {
        $handled = false;
        
        // 处理请求
        echo 'Handler1接受到了请求' . PHP_EOL;
        
        if (!$handled && $this->nextHandler) {
            $this->nextHandler->handler();
        }
    }
}
class Handler2 extends AHandler
{
    public function handler()
    {
        $handled = false;
        
        // 处理请求
        echo 'Handler2接受到了请求' . PHP_EOL;
        
        if (!$handled && $this->nextHandler) {
            $this->nextHandler->handler();
        }
    }
}
class Handler3 extends AHandler
{
    public function handler()
    {
        $handled = false;
        
        // 处理请求
        echo 'Handler3接受到了请求' . PHP_EOL;
        
        if (!$handled && $this->nextHandler) {
            $this->nextHandler->handler();
        }
    }
}

The usage code example is as follows:

$handler1 = new Handler1();
$handler2 = new Handler2();
$handler3 = new Handler3();
$handler1->setNext($handler2);
$handler2->setNext($handler3);

$handler1->handler();

Although the above code completes the structure of the chain of responsibility, there are still some problems. If the programmer does not understand the business or chain of responsibility model, If you are too clear, you may forget to add the following code to the handler method:

if (!$handled && $this->nextHandler) {
    $this->nextHandler->handler();
}

Then the chain of responsibility will be interrupted. In addition, if we have 10 or more processors, then 10 new processors will be created, and then setNext will be executed 9 times. If you accidentally write something wrong, you will be embarrassed.

Now, let’s modify the above code. The modified code is as follows:

abstract class AHandler
{
    protected $nextHandler = null;
    
    public function setNext (AHandler $handler)
    {
        $this->nextHandler = $handler;
    }
    
    // 使用了模板方法模式,防止程序员忘记写下段代码
    public function handler ()
    {
        if (!$this->doHandler() && $this->nextHandler) {
            $this->nextHandler->handler();
        }
    }
    
    abstract public function doHandler ();
}

class Handler1 extends AHandler
{
    public function doHandler()
    {
        $handled = false;
        
        // 处理请求
        echo 'Handler1接受到了请求' . PHP_EOL;
        
        return $handled;
    }
}
class Handler2 extends AHandler
{
    public function doHandler()
    {
        $handled = false;
        
        // 处理请求
        echo 'Handler2接受到了请求' . PHP_EOL;
        
        return $handled;
    }
}

class Handler3 extends AHandler
{
    public function doHandler()
    {
        $handled = false;
        
        // 处理请求
        echo 'Handler3接受到了请求' . PHP_EOL;
        
        return $handled;
    }
}

class HandlerChain
{
    private $handlerChains = [];
    
    public function __construct(array $handlerChains)
    {
        $this->handlerChains = $handlerChains;
    }
    
    public function addHandler (AHandler $handler)
    {
        $this->handlerChains[] = $handler;
    }
    
    public function handler ()
    {
        $hdCnt = count($this->handlerChains);
        
        for ($i = 0; $i < $hdCnt; $i ++) {
            if (isset($this->handlerChains[$i]) 
                  && isset($this->handlerChains[$i+1])) {
                $this->handlerChains[$i]->setNext($this->handlerChains[$i+1]);
            }
        }
        
        $this->handlerChains[0]->handler();
    }
}

Then, use the code as follows:

$handler1 = new Handler1();
$handler2 = new Handler2();
$handler3 = new Handler3();

$handerChian = new HandlerChain([$handler1, $handler2, $handler3]);
$handerChian->handler();

Simpler Implementation method

In fact, there is a simpler way to implement the chain of responsibility pattern, the code is as follows:

abstract class AHandler
{
    abstract public function handler ();
}

class Handler1 extends AHandler
{
    public function handler()
    {
        $handled = false;
        // 处理请求
        echo &#39;Handler1接受到了请求&#39; . PHP_EOL;
        return $handled;
    }
}

// Handler2、Handler3代码省略


class HandlerChain
{
    private $handlerChains = [];
    
    public function __construct(array $handlerChains)
    {
        $this->handlerChains = $handlerChains;
    }
    
    public function addHandler (AHandler $handler)
    {
        $this->handlerChains[] = $handler;
    }
    
    public function handler ()
    {
        foreach ($this->handlerChains as $handler) {
            if ($handler->handler()) {
                break;
            }
        }
    }
}

Summary

Through the chain of responsibility model, multiple processors have the opportunity to process requests. Dividing the original module into multiple processors for processing conforms to the single responsibility principle and greatly improves the readability of the code. In addition, it is very easy to expand. When new functions are needed, just add new processors.

The definition of the general design pattern is that if the processor cannot handle the request, it will pass the request to the next processor. In fact, it also has a variant, that is, each processor will handle the request.

The above is the detailed content of Understand the responsibility chain model of PHP design pattern in one article. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn