前端设计模式(责任链模式)

46 阅读2分钟

场景

我们在提交表单时,需要对数据接收时进行一系列校验,常见的有以下几种校验

  1. 必填项校验,如果数据无法满足业务所必须字段要求,数据一旦落入库中就会产生一系列问题
  2. 非法字符校验,因为数据如何录入,上游系统的录入规则是什么样的我们都不清楚,这一项规则也是必须的
  3. 长度校验,理由同上,如果系统某字段长度限制 50,但是接入来的数据 500长度,这也会造成问题

如果不使用责任链模式,上面说的真实同步场景面临两个问题

  1. 如果把上述说的代码逻辑校验规则写到一起,毫无疑问这个类或者说这个方法函数奇大无比。减少代码复杂性一贯方法是:将大块代码逻辑拆分成函数,将大类拆分成小类,是应对代码复杂性的常用方法。如果此时说:可以把不同的校验规则拆分成不同的函数,不同的类,这样不也可以满足减少代码复杂性的要求么。这样拆分是能解决代码复杂性,但是这样就会面临第二个问题
  2. 开闭原则:添加一个新的功能应该是,在已有代码基础上扩展代码,而非修改已有代码。大家设想一下,假设你写了三套校验规则,运行过一段时间,这时候领导让加第四套,是不是要在原有代码上改动

应用

class AbstractHandler {
    setNext(handler) {
        this.nextHandler = handler;
        return handler;
    }
    handle(request) {
        if (this.nextHandler) {
            return this.nextHandler.handle(request);
        }
        return null;
    }
}
class ConcreteHandler1 extends AbstractHandler {
    handle(request) {
        if (request === "type1") {
            return "Handled by Concrete Handler 1";
        }
        return super.handle(request);
    }
}
class ConcreteHandler2 extends AbstractHandler {
    handle(request) {
        if (request === "type2") {
            return "Handled by Concrete Handler 2";
        }
        return super.handle(request);
    }
}
class ConcreteHandler3 extends AbstractHandler {
    handle(request) {
        if (request === "type3") {
            return "Handled by Concrete Handler 3";
        }
        return super.handle(request);
    }
}
// 客户端代码
const handler1 = new ConcreteHandler1();
const handler2 = new ConcreteHandler2();
const handler3 = new ConcreteHandler3();
handler1.setNext(handler2).setNext(handler3);
console.log(handler1.handle("type2")); // 输出 "Handled by Concrete Handler 2"
console.log(handler1.handle("type4")); // 输出 null