坐着地铁学习职责链模式,一学就会

1,594 阅读3分钟

职责链模式,指的是由拥有处理能力的职责节点对象组成一个链条,一个请求从链条的开始或者中间进入,都有机会被后续的职责节点对象处理。进入职责链的请求,会沿着后续链条被传递,直到请求被处理才会终止传递。

身在帝都,每天挤地铁去搬砖,发现月初、月中和月末地铁的票价都不一样。

查看规则才发现,乘车消费超过150元打五折,超过100元打八折,不足100元不打折。

这里通过职责链模拟一个处理订单金额的功能,该方法传入消费总金额和当前车程的常规票价。

先看流程图:

image.png

先进入总消费大于150元的流程,当前消费金额是否大于150元,返回金额,请求结束。如果不是,进入下一个总消费大于100元的流程。

进入总消费大于100元的流程,当前消费金额是否大于100元,返回金额,请求结束。如果不是,进入下一个总消费不足100元的流程。

在总消费不足100元的流程中,所有的请求都会被处理。

下面进行具体的代码实现:

// 1、定义各职责节点对象
// 定义超过150元的职责节点对象
var consumption150 = function (consumption, fare) {
    if (consumption > 150) {
        console.log(`地铁总消费大于150元,本次${fare}元的票价折扣价${fare * 0.5}`);
    } else {
        return 'nextProcess'; // 传递给下一个流程
    }
};
// 定义超过100元的职责节点对象
var consumption100 = function (consumption, fare) {
    if (consumption > 100) {
        console.log(`地铁总消费大于100元,本次${fare}元的票价折扣价${fare * 0.8}`);
    } else {
        return 'nextProcess'; // 传递给下一个流程
    }
};
// 定义不足100元的职责节点对象
var consumptionNormal = function (consumption, fare) {
    console.log(`地铁总消费不足100元,本次${fare}元的票价依然收费${fare}元`);
};

// 2、设置链条构造函数
var Chain = function (selfFn) {
    this.selfFn = selfFn; // 自身函数
    this.process = null; // 下一个职责节点
};
Chain.prototype.setNextProcess = function (process) {
    return this.process = process; // 设置当前节点对象的下一个节点对象
};
Chain.prototype.handleRequest = function () {
    // 执行自身函数,并返回执行结果
    var ret = this.selfFn.apply(this, arguments);
    // 返回nextProcess表示当前职责节点不能处理请求,此时将请求交个下一个职责节点
    if (ret === 'nextProcess') {
        return this.process && this.process.handleRequest.apply(this.process, arguments);
    }
    return ret;
};
// 创建节点,包含自身selfFn和是否成功请求的标志nextProcess
var chainconsumption150 = new Chain(consumption150);
var chainconsumption100 = new Chain(consumption100);
var chainconsumptionNormal = new Chain(consumptionNormal);

// 3、设置节点间的链条关系,形成职责链
chainconsumption150.setNextProcess(chainconsumption100);
chainconsumption100.setNextProcess(chainconsumptionNormal);

1、职责链可以从任意节点进入

现在可以通过chainconsumption150.handleRequest(120, 8)的方式进入到职责链的第一个职责节点对象中。

也可以通过chainconsumption100.handleRequest(120, 8)的方式进入到职责链的第二个职责节点对象中。

2、职责链可以进行扩展

假如,总消费超过300元以后,可以打四折。

(1)定义职能节点对象

var consumption300 = function (consumption, fare) {
    if (consumption > 300) {
        console.log(`地铁总消费大于300元,本次${fare}元的票价折扣价${fare * 0.4}`);
    } else {
        return 'nextProcess'; // 传递给下一个流程
    }
};

(2)创建链条节点

var chainconsumption300 = new Chain(consumption300);

(3)把节点塞入到链条中

chainconsumption300.setNextProcess(chainconsumption150);

总结

职责链模式,支持链条长度的扩展,也支持在链条中进入的位置。