JavaScript设计模式之责任链模式实例分析

以下是“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方法中,我们首先对传入的字符串进行验证,如果当前验证器不能完成任务,则将请求传递给下一个验证器。最后,我们使用LengthValidatorSpecialCharsValidator组成了一条验证链,并进行了一次验证。

实例二

现在我们假设有一个工程师团队,需要按照工程师级别来审批加班申请。高级工程师可以审批自己及普通工程师的加班申请,而主管可以审批所有工程师的加班申请。我们同样可以使用责任链模式来实现这个需求。

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方法中,我们首先对传入的工程师和加班天数进行验证,如果当前审批者不能完成任务,则将审批请求传递给下一个审批者。最后,我们使用SeniorEngineerApproverDirectorApprover组成了一条审批链,并对所有工程师进行了加班申请审批。

结论

责任链模式是一种非常实用的设计模式,可以将复杂的操作逻辑分解成多个小的操作块,提高了代码的可读性和可维护性。在实际的工作中,我们经常会通过责任链模式来处理复杂的业务逻辑,如表单验证、请求处理、审批流程等。同时,在使用责任链模式时,我们需要注意类之间的依赖关系,避免形成循环依赖。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript设计模式之责任链模式实例分析 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java安全之Tomcat6 Filter内存马问题

    Java安全之Tomcat6 Filter内存马问题完整攻略 背景 Tomcat是一个开放源代码的Web应用服务器,支持多种Web开发技术,包括Java Servlet、JavaServer Pages(JSP)和JavaServer Faces(JSF)等。然而,在使用Tomcat时,可能会存在一些安全问题,比如内存马问题。本篇攻略旨在详细介绍Tomcat…

    Java 2023年6月2日
    00
  • java 生成xml并转为字符串的方法

    一、Java 生成 XML 的两种方式 Java 可以通过两种方式来生成 XML:DOM 方式和 SAX 方式。DOM 方式使用内存模型来存储 XML 文件,而 SAX 方式则使用事件驱动模式来解析 XML 文件。 DOM 方式 在 DOM 方式下,Java 代码会把整个 XML 文件加载到内存中,在内存模型中修改和操作节点。可以使用标准的 Java DOM…

    Java 2023年5月27日
    00
  • SpringBoot3整合MyBatis出现异常:Property ‘sqlSessionFactory’or ‘sqlSessionTemplate’ are required

    Spring Boot是目前非常受欢迎的开发框架,而MyBatis是一款优秀的数据库ORM框架,二者结合可以让我们开发高效率、高质量的Web应用。不过在整合Spring Boot和MyBatis的时候,有时候会遇到”Property ‘sqlSessionFactory’ or ‘sqlSessionTemplate’ are required”异常,那么该…

    Java 2023年5月20日
    00
  • Spring Data Jpa的四种查询方式详解

    下面是关于“Spring Data Jpa的四种查询方式详解”的完整攻略: Spring Data Jpa的四种查询方式详解 Spring Data Jpa是一个简化了JPA规范的框架,它提供了许多便利的功能,其中最重要的就是提供了四种查询方式。 命名查询 命名查询是指根据方法名进行查询。Spring Data Jpa会根据方法名的规则自动生成查询语句,无需…

    Java 2023年5月20日
    00
  • 详解SpringBoot定时任务说明

    下面我来详细讲解一下“详解SpringBoot定时任务说明”的完整攻略。 什么是SpringBoot定时任务? SpringBoot定时任务是指在特定的时间或周期性的执行一些任务,比如定时生成报表、清理数据库等。SpringBoot框架中提供了丰富的定时任务支持,可以通过简单的配置来实现这些任务。 定时任务的实现方式 基于注解和功能接口实现定时任务 Spri…

    Java 2023年5月19日
    00
  • 浅谈Java包装类型Long的==操作引发的低级bug

    让我来详细讲解一下关于“浅谈Java包装类型Long的==操作引发的低级bug”的攻略。 什么是Java包装类型 Java包装类型是Java针对基本数据类型提供的类型封装。Java中共有八种基本数据类型,分别是byte、short、int、long、float、double、char和boolean。而Java的基本数据类型都不是对象,因此不能参与到Java…

    Java 2023年5月25日
    00
  • Java Predicate及Consumer接口函数代码实现解析

    Java中的Predicate和Consumer是两种常用的函数式接口,它们可以让我们编写更为简洁、灵活的代码,特别是在处理集合、流等数据时非常有用。 Predicate Predicate可以理解为谓词或者断言,它接受一个输入参数,返回一个布尔类型的值。通常情况下,我们使用Predicate来过滤集合或者流中的数据。 下面是Predicate接口的定义: …

    Java 2023年5月26日
    00
  • Spring Security过滤器链体系的实例详解

    Spring Security过滤器链体系的实例详解 什么是Spring Security过滤器链体系 Spring Security过滤器链体系是Spring Security的核心内容之一,它负责对用户请求进行安全过滤和授权校验。在Spring Security过滤器链体系中,每一个过滤器都有着不同的用途和功能,并且这些过滤器按一定的顺序组成一条链式结构…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部