Make multiple objects have the opportunity to process the request, so as to avoid the coupling relationship between the sender and receiver of the request, connect these objects into a chain, and pass the request along the chain until an object can process it. These objects in the transmission chain are called nodes.
In practical application, the responsibility chain model is often used in the reconstruction of cumbersome if... if else... Which is similar to the strategy model learned before. Compared with strategy, the responsibility chain model is logically more cumbersome, but the responsibility chain model has greater flexibility.
If the result of the previous link needs to be handed over to the next link to continue processing, then the responsibility chain mode is more suitable for processing at this time.
Next, suppose a requirement
An e-commerce website,
When users pay a 500 deposit and the deposit has been paid, they can enjoy a 500 coupon, which is not limited by the quantity of goods;
When users pay 200 deposit and the deposit has been paid, they can enjoy 500 coupons, which is not limited by the quantity of goods;
When the user does not pay the deposit, it is limited by the quantity of goods. When there is goods, it can be bought at the original price, and when there is no goods, it can not be bought.
var buyOrder = function(orederType, pay, stock){ if(orederType == 1){ if(pay){ console.log('500 coupon'); } else { if(stock > 0){ console.log('General shopping page'); } else { console.log('Out of stock'); } } } else if(orederType == 2){ if(pay){ console.log('200 coupon'); } else { if(stock > 0){ console.log('General shopping page'); } else { console.log('Out of stock'); } } } else if(orederType == 3){ if(stock > 0){ console.log('General shopping page'); } else { console.log('Out of stock'); } } } buyOrder(1, true, 600)
Next, call it
//Three order functions, all of which are node functions const order500 = function (orderType, pay, stock) { if (orderType == '1' && pay == true) { console.log('500 coupon'); } else { return 'nextSuccessor'; // No matter who the next node is, it is to pass the request back } } const order200 = function (orderType, pay, stock) { if (orderType == '2' && pay == true) { console.log('200 coupon'); } else { return 'nextSuccessor'; // No matter who the next node is, it is to pass the request back } } const orderNormal = function (orderType, pay, stock) { if (stock > 0) { console.log('General shopping page'); } else { console.log('Out of stock'); } } //Wrap the three order functions into the nodes of the responsibility chain const chainOrder500 = new Chain(order500) const chainOrder200 = new Chain(order200) const chainOrderNormal = new Chain(orderNormal) //Then specify the order of nodes in the responsibility chain chainOrder500.setNextSuccessor(chainOrder200) chainOrder200.setNextSuccessor(chainOrderNormal) //Finally, pass the request to the first node and start the responsibility chain mode chainOrder500.handleRequest(1, true, 500) //500 coupons chainOrder500.handleRequest(3, true, 20) //General shopping page chainOrder500.handleRequest(3, true, 0) //Out of stock
Then let's share another example:
There is an active H5 page, which is used in multiple browser environments, such as wechat, QQ, self-developed apps, other third-party apps, etc. Because the background interface handles different login states in different environments, it is necessary to judge different environments, take different values in cookie s, and transfer different login state token s. Sometimes, there are some special processing for network requests for some special environments.
The following is an example of typescript. You can see that BaseHandler is an abstract class, indicating that it must be attached to another instance
// Request interceptor responsibility chain node abstract class export default abstract class BaseHandler { // Next node private nextHandler: BaseHandler | null = null; // Set next node public setNextHandler (handler: BaseHandler): BaseHandler { this.nextHandler = handler; return this.nextHandler; } // The method of calling the node handles the request, and then calls the next node to continue processing. public handleRequest (config: any): void { // Processing of current node if (this.checkHandler(config)) { this.handler(config); } // Proceed to the next node if (this.nextHandler) { this.nextHandler.handlerRequest(config); } } // Call the method of the node to process the request. If a node handles the request, it will exit directly (mutually exclusive) public handleRequestOnce(config: any): void { // Processing of current node if (this.checkHandle(config)) { this.handler(config); } else if (this.nextHandler) { this.nextHandler.handleRequestOnce(config); } } // Determine whether to process at this node abstract checkHandle(config: any): boolean; // Treatment method abstract handler(config: any): void; } /* Author: lucio has come to learn all about it Link: https://juejin.cn/post/7055149674650402824 Source: rare earth Nuggets The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source. */
import BaseHandler from '../../base-handler'; import { getUrlPara } from '../../../url'; import { env } from '../../../env'; // Handle request parameters of H5 embedded in applet export default class WechatMpParamsHandler extends BaseHandler { // In the king's life applet and QQ login, the applet login status is used. In other cases, the wechat login status is used checkHandle(): boolean { return env.isMiniProgram; } handler(config: any): any { if (getUrlPara('_ticket')) { config.params._ticket = getUrlPara('_ticket'); } return config; } } /* Author: lucio has come to learn all about it Link: https://juejin.cn/post/7055149674650402824 Source: rare earth Nuggets The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source */
Finally, the call is implemented in the axios interceptor
// request interceptor const requestInterceptor = function (config) { const requestHandlerChain = new UrlInterceptor(); // Requested responsibility chain node: URL processing of CGI requestHandlerChain.setNextHandler(new ParamsInterceptor()); // Requested responsibility chain node: parameter processing of CGI requestHandlerChain.handleRequest(config); return config; }; // Response interceptor const responseInterceptor = (response) => { const responseHandlerChain = new ParseDataInterceptor(); // Responsibility chain node of returned data: analyze the data of new and old frameworks responseHandlerChain.setNextHandler(new LoginInfoInterceptor()) // Responsibility chain node that returns data: process login information .setNextHandler(new ErrorToastInterceptor()); // Responsibility chain node of returned data: handling error prompt responseHandlerChain.handleRequest(response); return response; }; // request interceptor axiosInstance.interceptors.request.use(requestInterceptor, error => Promise.reject(error)); // Response interceptor axiosInstance.interceptors.response.use(responseInterceptor, error => Promise.reject(error)); /* Author: lucio has come to learn all about it Link: https://juejin.cn/post/7055149674650402824 Source: rare earth Nuggets The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source. */
Above to be continued