前端设计模式(七):责任链模式
作者:互联网
参考文章:
- 实现过滤或校验逻辑的最优方案:[https://juejin.cn/post/7026400720085581861]
- 前端的设计模式系列-责任链模式: [https://blog.csdn.net/qiwoo_weekly/article/details/122816843]
在日常业务开发中,你可能会常常去校验一个参数或者过滤一些对象,在各种if(判断条件){执行这个分支逻辑} 后,你的代码会越来越臃肿,责任链模式就是为了解决这个问题,让业务逻辑解耦合,可扩展
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
示意图:
用职责链模式改进后:
责任链的类实现方式:
/**
* 定义参数校验抽象类,指定行为,确定每个链通用逻辑
*/
class AbstractParamsChainHandler {
constructor() {
this.nextHandler = null;
}
setNextHandler(nextHandler) {
this.nextHandler = nextHandler;
}
getNextHandler() {
return this.nextHandler;
}
doValidate(params){
throw new Error('必须由子类重写的验证方法');
}
executeValidateChain(params){
let validate_result = this.doValidate(params);
if(!validate_result) return;
if (this.getNextHandler){
this.getNextHandler()?.executeValidateChain.call(this.getNextHandler(),params);
}
}
}
/**
* 空参数校验
*/
class EmptyCheckHandler extends AbstractParamsChainHandler {
doValidate(params) {
if(['', undefined, null].includes(params)){
console.log('EmptyCheckHandler: 当前参数为空,校验不通过');
return false
}
return true
}
}
/**
* 参数不能包含空格校验
*/
class WhiteSpaceCheckHandler extends AbstractParamsChainHandler {
doValidate(params) {
if(/\s+/g.test(params)){
console.log('EmptyCheckHandler: 当前参数包含空格,校验不通过');
return false
}
return true
}
}
/**
* 不能超过指定长度
*/
class WordLengthCheckHandler extends AbstractParamsChainHandler {
constructor(wordLength) {
super();
this.wordLength = wordLength
}
doValidate(params) {
if(params.length > this.wordLength){
console.log(`WordLengthCheckHandler: 长度校验不通过,当前文字长度: ${params.length},限制的长度: ${this.wordLength}`);
return false
}
return true
}
}
class ParamsCheckService {
/**
* 假设对用户名进行监测
* @param name
*/
static userNameCheck(name){
const empty_handler = new EmptyCheckHandler();
const whitespace_handler = new WhiteSpaceCheckHandler();
const word_handler = new WordLengthCheckHandler(5);
empty_handler.setNextHandler(word_handler);
word_handler.setNextHandler(whitespace_handler);
empty_handler.executeValidateChain(name);
}
}
ParamsCheckService.userNameCheck('')
function实现方式
以打印日志等级为例,探索函数式的实现方式
1.我们先实现一个 Handler
对象,构建链条:
const Handler = function (fn) {
this.handler = fn;
this.next = null;
};
Handler.prototype.setNext = function setNext(h) {
this.next = h;
return h;
};
Handler.prototype.passRequest = function () {
const ret = this.handler.apply(this, arguments);
this.next && this.next.passRequest.apply(this.next, arguments);
};
2.接下来实现不同的 Logger
const ERR = 3;
const NOTICE = 5;
const DEBUG = 7;
const StdoutLogger = function (msg, level) {
// 根据等级判断自己是否处理
if (level <= DEBUG) {
console.log("Writting to stdout: " + msg);
}
};
const EmailLogger = function (msg, level) {
// 根据等级判断自己是否处理
if (level <= NOTICE) {
console.log("Sending via email: " + msg);
}
};
const StderrLogger = function (msg, level) {
// 根据等级判断自己是否处理
if (level <= ERR) {
console.log("Sending to stderr: " + msg);
}
};
3.测试
const StdoutHandler = new Handler(StdoutLogger);
const EmailHandler = new Handler(EmailLogger);
const StderrHandler = new Handler(StderrLogger);
StdoutHandler.setNext(EmailHandler).setNext(StderrHandler);
StdoutHandler.passRequest("Entering function y.", DEBUG);
StdoutHandler.passRequest("Step1 completed.", NOTICE);
StdoutHandler.passRequest("An error has occurred.", ERR);
链式函数再职责链中的运用
这个例子来自于《JavaScript高级程序设计第四版》,下面是部分代码
Function.prototype.after = function( fn ){
var self = this;
return function(){
var ret = self.apply( this, arguments );
if ( ret === 'nextSuccessor' ){
return fn.apply( this, arguments );
}
return ret;
}
};
用职责链模式获取文件上传对象
var getActiveUploadObj = function () {
try {
return new ActiveXObject("TXFTNActiveX.FTNUpload"); // IE 上传控件
} catch (e) {
return 'nextSuccessor';
}
};
var getFlashUploadObj = function () {
if ( supportFlash() ) {
var str = '<object type="application/x-shockwave-flash"></object>';
return $(str).appendTo($('body'));
}
return 'nextSuccessor';
};
var getFormUpladObj = function () {
return $('<form><input name="file" type="file"/></form>').appendTo($('body'));
};
var getUploadObj = getActiveUploadObj.after(getFlashUploadObj).after(getFormUpladObj);
console.log(getUploadObj());
标签:function,const,前端,责任,handler,params,new,return,设计模式 来源: https://www.cnblogs.com/suanyunyan/p/16434917.html