php design pattern (1) -- observer pattern -- spl standard writing
php design pattern (2) -- observer pattern -- using trait to improve writing
php design pattern (3) -- responsibility Chain (Chain of Responsibility) Pattern
PHP Design Pattern (4) -- Decorator Pattern
This time we discuss the chain of responsibility.
Analysis
In fact, the chain of responsibility imagines the middleware in software development. There is only one request, but there will be many processing objects, each processing object contains the next object, and each processing object has the right to process.
Primary role, the processing class, and its common interface
Secondary role, the request object.
There are a lot of codes on the Internet, mainly for an employee's request for leave, which is too boring. Next, I construct a requirement, assuming that the request is that the user wants to change his own password, so the request object contains the request url, user name, original password, and new password.
There is also a requirement that the user checks his followers without logging in for verification.
During processing, I will log all requests, here is a processing class.
During processing, some requests need to verify the user's password, and some do not. This is a login verification request.
During processing, if the request url is wrong, an error will be reported.
So in total, it is a log processor, a login verification processor, a password modification processor, and a query fan processor.
Experience, this mode can have a return value or no return value. random.
Lesson 2: Construct the chain of responsible handlers, in the client code, please be aware of this.
Code
<?php /** * Common abstract interface of the processors of the chain of responsibility */ abstract class Handler { protected $successor; // handle the request object abstract public function handleRequest($request); // Set up the next handler. public function setSuccessor(Handler $next_handler){ $this->successor = $next_handler; } } /** * This is the request object */ class Request { public $url; public $username; public $password; public $request_parameter; public function __construct($url,$username, $password, array $request_parameter){ $this->url=$url; $this->username=$username; $this->password=$password; $this->request_parameter=$request_parameter; } } /** * log handler */ class Log extends Handler { public function handleRequest($request) { echo "url:{$request->url}; request_parameter:" . json_encode($request->request_parameter) . PHP_EOL; if ($this->successor) { // Pass the request directly return $this->successor->handleRequest($request); } return ['code'=>0]; } } /** * Identity verification processor, should use database, here is replaced by array */ class Verification extends Handler { protected $all_user; protected $all_url; public function __construct(){ $this->all_users = [ 'name1' =>'123', 'name2' => '456', ]; $this->check_urls = [ 'change_password', ]; } private function continue_request($request){ if ($this->successor) { // Pass the request directly return $this->successor->handleRequest($request); } } public function handleRequest($request) { if (in_array( $request->url, $this->check_urls )) { if ( array_key_exists($request->username, $this->all_users ) && $request->password == $this->all_users[$request->username] ) { return $this->continue_request($request); } else { return ['code'=>0,'message'=>'user authentication error' ]; } }else { return $this->continue_request($request); } } } /** * Modify the password processor * Modify the database code slightly. */ class ChangePassword extends Handler { public function handleRequest($request) { if ($request->url == 'change_password') { // Here you can continue to check whether the parameters are correct, the code is omitted return ['code'=>1,'data'=> "Hello {$request->username}, the password is changed successfully, the new password is {$request->request_parameter['new_password']}"]; } if ($this->successor) { // Pass the request directly return $this->successor->handleRequest($request); } return ['code'=>0,'message'=>'url is invalid']; } } /** * Check fans, replace the database code with an array */ class QueryFans extends Handler { protected $all_user; public function __construct(){ $this->all_users = [ 'name1' => 'Your fans are name3,name4', 'name2' => 'Your fans are name5,name6,name7', ]; } public function handleRequest($request) { if ($request->url == 'query_fans') { if (array_key_exists( $request->username, $this->all_users )) { return ['code'=>1,'data'=> "{$request->username}您好,". $this->all_users[ $request->username ] ]; }else { return ['code'=>0,'message' =>'user does not exist' ]; } } if ($this->successor) { // Pass the request directly return $this->successor->handleRequest($request); } return ['code'=>0,'message'=>'url is invalid']; } } /** * Client code, verifying the chain of responsibility design pattern */ class Client { public function __construct(){ $change_pass_handler = new ChangePassword(); $query_handler = new QueryFans(); $log_handler = new Log(); $verification = new Verification(); $log_handler->setSuccessor($verification); $verification->setSuccessor($change_pass_handler); $change_pass_handler->setSuccessor($query_handler); $request = new Request('luanxie_url', '', '', []); $result = $log_handler->handleRequest($request); // use log as first handler $this->print_result($result); // deliberately wrong password $request = new Request('change_password', 'name1', '1266', ['new_password'=>'124']); $result = $log_handler->handleRequest($request); $this->print_result($result); // Deliberately write non-existent users $request = new Request('change_password', 'name444', '123', ['new_password'=>'124']); $result = $log_handler->handleRequest($request); $this->print_result($result); // This time it's spec-compliant. $request = new Request('change_password', 'name1', '123', ['new_password'=>'124']); $result = $log_handler->handleRequest($request); $this->print_result($result); //Fan query, business logic stipulates: no need to verify the password, it doesn't matter if it is wrong $request = new Request('query_fans', 'name1', '12789', []); $result = $log_handler->handleRequest($request); $this->print_result($result); } private function print_result($result) { if ($result['code']==1) { echo $result['data']; }else { echo $result['message']; } echo PHP_EOL.PHP_EOL; } } new Client();
Results display
url:luanxie_url; request_parameter:[] url is invalid url:change_password; request_parameter:{"new_password":"124"} User authentication error url:change_password; request_parameter:{"new_password":"124"} User authentication error url:change_password; request_parameter:{"new_password":"124"} Hello name1, the password has been changed successfully, the new password is 124 url:query_fans; request_parameter:[] Hello name1, your fans are name3,name4