资讯专栏INFORMATION COLUMN

JS设计模式——职责链模式

piapia / 2871人阅读

摘要:用实现职责链这里使用变量存储上一个函数,存储的是最后一个调用返回的函数。理解了过程也就会知道这句代码是为后面的函数准备的建议如果某块功能中存在大量的可以考虑使用职责链模式

职责链模式

1. 职责链定义

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将对象连成一条链,并沿着这个链传递该请求,直到有一个对象处理它为止

2.职责链优点

请求发送者只需要知道链中的第一个节点,从而弱化了发送者和一组接受者之间的强联系

3.职责链缺点

职责链模式使得程序中多了一些节点对象,在某次请求传递过程中,大部分节点并没有实质性作用,只是让请求传递下去,从性能方面考虑,要避免过长的职责链带来的性能耗损

4.职责链使用场景 4.1 基础例子

商城做活动,预付定金500且购买的客户可返现100,预付定金200且购买的客户可返现50,普通购买则没有返现且库存不够买不到。

    //设置每个节点的操作,即每种用户对应的操作,如果不能该节点不能操作则传递给下一个节点。
var order500 = function (orderType, pay, stock) {
    if (orderType === 1 && pay === true) {
        console.log("100")
    } else {
        return "nextSuccessor"
    }
}
var order200 = function (orderType, pay, stock) {
    if (orderType === 2 && pay === true) {
        console.log("50")
    } else {
        return "nextSuccessor"
    }
}
var order = function (orderType, pay, stock) {
    if (stock > 0) {
        console.log("buy")
    } else {
        console.log("lack")
    }
}
//职责链,规定每个节点的下一个节点,执行本节点的函数
function Chain(fn) {
    this.fn = fn
    this.nextSuccessor = null
}
Chain.prototype.setNextSuccessor = function (successor) {
    this.nextSuccessor = successor
}
Chain.prototype.passRequest = function () {
    var ret = this.fn.apply(this, arguments)
    if (ret === "nextSuccessor") {
        return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments)
    }
}
//把每个节点都放到职责链中
var chainOrder500 = new Chain(order500)
var chainOrder200 = new Chain(order200)
var chainOrder = new Chain(order)
//设置职责链的下一个节点
chainOrder500.setNextSuccessor(chainOrder200)
chainOrder200.setNextSuccessor(chainOrder)
//设定从某个职责链节点开始执行
chainOrder500.passRequest(1, true, 1)
4.2 异步职责链
//设置每个节点的操作,即每种用户对应的操作,如果不能该节点不能操作则传递给下一个节点。
var order500 = function (orderType, pay, stock) {
    if (orderType === 1 && pay === true) {
        console.log("100")
    } else {
        return "nextSuccessor"
    }
}
var order200 = function (orderType, pay, stock) {
    var self = this
    setTimeout(function () {
        self.next()
    }, 1000)
    // if (orderType === 2 && pay === true) {
    //     console.log("50")
    // } else {
    //     return "nextSuccessor"
    // }
}
var order = function (orderType, pay, stock) {
    if (stock > 0) {
        console.log("buy")
    } else {
        console.log("lack")
    }
}
//职责链,规定每个节点的下一个节点,执行本节点的函数
function Chain(fn) {
    this.fn = fn
    this.nextSuccessor = null
}
Chain.prototype.setNextSuccessor = function (successor) {
    this.nextSuccessor = successor
}
Chain.prototype.passRequest = function () {
    var ret = this.fn.apply(this, arguments)
    if (ret === "nextSuccessor") {
        return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments)
    }
}
Chain.prototype.next = function () {
    return (this.nextSuccessor) && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments)
}
// 把每个节点都放到职责链中
var chainOrder500 = new Chain(order500)
var chainOrder200 = new Chain(order200)
var chainOrder = new Chain(order)
//设置职责链的下一个节点
chainOrder500.setNextSuccessor(chainOrder200)
chainOrder200.setNextSuccessor(chainOrder)
// 设定从某个职责链节点开始执行
chainOrder500.passRequest(1, false, 1)

这里需要增加一个next函数,手动传递到下一个节点。

4.3 用AOP实现职责链
var order500 = function (orderType, pay, stock) {
    if (orderType === 1 && pay === true) {
        console.log("100")
    } else {
        return "nextSuccessor"
    }
}
var order200 = function (orderType, pay, stock) {
    if (orderType === 2 && pay === true) {
        console.log("50")
    } else {
        return "nextSuccessor"
    }
}
var order = function (orderType, pay, stock) {
    if (stock > 0) {
        console.log("buy")
    } else {
        console.log("lack")
    }
}

Function.prototype.after = function (fn) {
    var self = this
    return function () {
        var ret = self.apply(this, arguments)
        if (ret === "nextSuccessor") {
            return fn && fn.apply(this, arguments)
        }
        return ret
    }
}
var func = order500.after(order200).after(order)
func(1, true, 3)

这里使用self变量存储上一个函数,func存储的是最后一个调用after返回的函数。一旦调用func函数,会先执行self保存的函数,会追根溯源一直到到最开始的self保存的函数order500。这里利用了闭包的特性保留了每一个self变量。整个函数的执行过程有点像倒序的递归。理解了过程也就会知道return ret这句代码是为后面的函数准备的~

5. 建议

如果某块功能中存在大量的if else可以考虑使用职责链模式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97037.html

相关文章

  • JS每日一题:设计模式-如何理解职责模式?

    摘要:提交请求的对象并不明确知道哪一个对象将会处理它也就是该请求有一个隐式的接受者。 20190412期 设计模式-如何理解职责链模式? 定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止 也就是说,请求以后,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提...

    lifesimple 评论0 收藏0
  • JavaScript设计模式----职责模式

    摘要:使用面向切面编程来快速的创建职责链的具体概念可以参考装饰者模式实现职责链简单又巧妙,但这种把函数叠在一起的方式,同时也叠加了函数的作用域,如果链条太长的话,也会对性能造成太大的影响。在开发中,职责链模式是最容易被忽视的模式之一。 声明:这个系列为阅读《JavaScript设计模式与开发实践》 ----曾探@著一书的读书笔记 1.职责链模式的定义 2. 2.1 简单职责链模式 2....

    boredream 评论0 收藏0
  • 传递请求之职责模式

    摘要:想一想,这个和我们的迭代器模式有着异曲同工的妙处,迭代器模式同样也是遍历选出最优解,但是相比而言,职责链模式的直观性个书写的幸福感是远远超过迭代器模式的。 职责链模式其实很好理解,由于一个链字出卖了它的灵魂。我们可以从这个字得到很大的提示。首先这个模式一定有传递性,而且,节点是可以重复拼接的,并且每个节点都具有一定的过滤功能,一定的职责。 是不是想起了组合模式里的一些内容呢? 是的,他...

    wslongchen 评论0 收藏0
  • Java设计模式职责模式

    摘要:简介职责链模式有时候也叫责任链模式,它是一种对象行为的设计模式。中的就是使用了责任链模式。纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。 Java设计模式之职责链模式 前几天复习java的异常处理时,接触到了责任链模式。在企业级应用中,从前台发过来的请求在后台抛出异常,异常处理的设计一般...

    bergwhite 评论0 收藏0
  • 《JavaScript设计模式与开发实践》读书笔记

    摘要:订阅模式的一个典型的应用就是后面会写一篇相关的读书笔记。享元模式享元模式的核心思想是对象复用,减少对象数量,减少内存开销。适配器模式对目标函数进行数据参数转化,使其符合目标函数所需要的格式。 设计模式 单例模式 JS的单例模式有别于传统面向对象语言的单例模式,js作为一门无类的语言。使用全局变量的模式来实现单例模式思想。js里面的单例又分为普通单例和惰性单例,惰性单例指的是只有这个实例...

    Panda 评论0 收藏0

发表评论

0条评论

piapia

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<