以下是“JavaScript设计模式之责任链模式实例分析”完整攻略。
标题
JavaScript设计模式之责任链模式实例分析
简介
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它用于将请求沿着处理程序链进行传递,直到其中一个处理程序能够处理该请求。该模式允许多个对象处理请求,而不必相互引用,并且请求发送者和接收者都没有对方的明确信息。责任链模式通常用于处理日志记录和错误处理等场景。
在JavaScript中,常常使用责任链模式来处理复杂的逻辑。下面我们通过两个实例来详细讲解JavaScript的责任链模式。
具体分析
实例一
假设有一个表单,需要验证用户输入的内容是否符合要求,包括长度是否合格、是否包含特殊字符等。为了使验证过程更加灵活和可扩展,我们可以使用责任链模式来实现。
class Validator {
constructor() {
this.nextItem = null;
}
setNextItem(item) {
this.nextItem = item;
return item;
}
handle(request) {}
}
class LengthValidator extends Validator {
constructor(minLength, maxLength) {
super();
this.minLength = minLength;
this.maxLength = maxLength;
}
handle(request) {
const length = request.length;
if (length >= this.minLength && length <= this.maxLength) {
if (this.nextItem !== null) {
return this.nextItem.handle(request);
}
return true;
}
return false;
}
}
class SpecialCharsValidator extends Validator {
constructor(specialChars) {
super();
this.specialChars = specialChars;
}
handle(request) {
for (let i = 0; i < request.length; i++) {
if (this.specialChars.indexOf(request.charAt(i)) !== -1) {
return false;
}
}
if (this.nextItem !== null) {
return this.nextItem.handle(request);
}
return true;
}
}
const validator = new LengthValidator(6, 16);
validator.setNextItem(new SpecialCharsValidator(['@', '#', '$']));
const valid = validator.handle('abc&&&');
console.log(valid); // 输出 false
在上面的代码中,我们首先定义了一个Validator
类,作为所有验证类的基类。然后定义了一个LengthValidator
类,用于验证字符串的长度是否合格,以及一个SpecialCharsValidator
类,用于验证字符串是否包含特殊字符。在handle
方法中,我们首先对传入的字符串进行验证,如果当前验证器不能完成任务,则将请求传递给下一个验证器。最后,我们使用LengthValidator
和SpecialCharsValidator
组成了一条验证链,并进行了一次验证。
实例二
现在我们假设有一个工程师团队,需要按照工程师级别来审批加班申请。高级工程师可以审批自己及普通工程师的加班申请,而主管可以审批所有工程师的加班申请。我们同样可以使用责任链模式来实现这个需求。
class Engineer {
constructor(name, level) {
this.name = name;
this.level = level; // level:1 表示普通工程师,level:2 表示高级工程师
}
}
class Approver {
constructor() {
this.nextApprover = null;
}
setNextApprover(approver) {
this.nextApprover = approver;
return approver;
}
approve(engineer, days) {}
}
class SeniorEngineerApprover extends Approver {
approve(engineer, days) {
if (engineer.level === 2 && days < 3) {
console.log(`${engineer.name}的加班申请已经被高级工程师审批通过`);
return true;
}
if (this.nextApprover !== null) {
return this.nextApprover.approve(engineer, days);
}
return false;
}
}
class DirectorApprover extends Approver {
approve(engineer, days) {
console.log(`${engineer.name}的加班申请已经被主管审批通过`);
return true;
}
}
// 创建工程师数组
const engineers = [
new Engineer('张三', 1),
new Engineer('李四', 2),
new Engineer('王五', 1),
];
// 创建责任链
const seniorEngineer = new SeniorEngineerApprover();
const director = new DirectorApprover();
seniorEngineer.setNextApprover(director);
// 处理加班申请
engineers.forEach(engineer => {
const days = Math.floor(Math.random() * 5);
seniorEngineer.approve(engineer, days);
})
在上面的代码中,我们首先定义了一个Engineer
类,用于表示工程师的基本信息。然后定义了一个Approver
类,作为所有审批类的基类。然后定义了一个SeniorEngineerApprover
类,用于处理高级工程师的加班申请,以及一个DirectorApprover
类,用于处理主管的加班申请。在approve
方法中,我们首先对传入的工程师和加班天数进行验证,如果当前审批者不能完成任务,则将审批请求传递给下一个审批者。最后,我们使用SeniorEngineerApprover
和DirectorApprover
组成了一条审批链,并对所有工程师进行了加班申请审批。
结论
责任链模式是一种非常实用的设计模式,可以将复杂的操作逻辑分解成多个小的操作块,提高了代码的可读性和可维护性。在实际的工作中,我们经常会通过责任链模式来处理复杂的业务逻辑,如表单验证、请求处理、审批流程等。同时,在使用责任链模式时,我们需要注意类之间的依赖关系,避免形成循环依赖。