JavaScript设计模式-职责链模式(22)

简介: JavaScript设计模式-职责链模式(22)

职责链设计模式是一种链式调用操作的设计模式,由于其使用可以接收上一个数据,且传递给下一个类型,所以被称为链式调用操作


在我们业务中常见的职责链模式有:作用域链,原型链,DOM节点中的事件冒泡以及处理多个请求的状态下,这些都可以在他们身上看到职责链设计模式

职责链案例


我们来做一个案例,当地汽车经销商做了一个活动,在活动当天缴纳200元汽车定金可在购车时抵1000元,缴纳400元汽车定金可在购车时抵2000元,没有缴纳汽车定金的人只能原价购买汽车,且有可能需要提前预定汽车


如果我们常规去写的情况代码会显得比较冗余,我们通过接收4个参数,再在里面进行判断以此得出最终购车金额或者无库存的时候进行提示

//总金额 库存 定金金额 是否付过定金 
        function business(amount, stock, depositamt, flag) {
            // 定金抵扣数据
            let deposit = [{
                key: 200,
                value: 1000
            }, {
                key: 400,
                value: 2000
            }]
            // 判断是否缴纳定金以及是否有库存
            if (flag && stock > 0) {
                // 判断定金缴纳金额
                let depositAmount = deposit.filter(R => R.key == depositamt);
                console.log(`您所购买的车辆原价为${amount}元,折扣后为${amount - depositAmount[0].value}元`);
            } else {
                // 判断是否拥有库存
                if (stock > 0) {
                    console.log(`您所购买的汽车价格为${amount}元!`);
                } else {
                    // 判断是否缴纳过定金
                    if (flag) {
                        console.log('汽车暂无库存了,您所心仪的车辆到货我们将第一时间通知,请耐心等待');
                    } else {
                        console.log('汽车暂无库存了,需要您先预定,半个月后可来提车');
                    }
                }
            }
        }

使用

business(10000, 1, 200, true)
business(10000, 1, 400, true)
business(10000, 0, 400, true)
business(10000, 1)
business(10000, 0)

如果需求被修改上述做法就不是特别合适,我们可以使用职责链设计模式改造一下,先把每个定金抵扣的函数都抽离出来单独处理,然后再声明一个构造函数以便实现链式调用功能,定金折扣函数结合构造函数进行使用且添加后续执行函数,如果定金函数不能处理则可以返回一个特定的标记,通过该标记进行链式调用

定金折扣函数

//总金额 库存 定金金额 是否付过定金 
        function depositamt400(amount, stock, depositamt, flag) {
            // 判断是否拥有库存且交过400块钱定金
            if (depositamt == 400 && flag && stock) {
                console.log(`您所购买的车辆原价为${amount}元,折扣后为${amount - (depositamt * 5)}元`);
            } else {
                return 'next'
            }
        }
        function depositamt200(amount, stock, depositamt, flag) {
            // 判断是否拥有库存且交过200块钱定金
            if (depositamt == 200 && flag && stock) {
                console.log(`您所购买的车辆原价为${amount}元,折扣后为${amount - (depositamt * 5)}元`);
            } else {
                return 'next'
            }
        }
        function orderNormal(amount, stock, depositamt, flag) {
            // 判断是否有库存
            if (stock) {
                console.log(`您所购买的汽车价格为${amount}元!`);
            } else {
                // 判断是否缴纳过定金
                if (flag) {
                    console.log('汽车暂无库存了,您所心仪的车辆到货我们将第一时间通知,请耐心等待');
                } else {
                    console.log('汽车暂无库存了,需要您先预定,半个月后可来提车');
                }
            }
        }

链式调用构造函数

// 创建一个构造函数
        class Automobile {
            constructor(fn) {
                // 接收一个函数
                this.fn = fn;
                //下一个会进行执行的函数
                this.success = null;
            }
            // 设置下一个进行执行的函数
            setNextSuccess = function (success) {
               this.success = success;
            }
            // 进行执行函数
            passRequest = function () {
                // 把当前函数定向到当前实例上面
                let ret = this.fn.apply(this, arguments)
                // 判断是否返回继续执行标记
                if (ret === 'next') {
                    // 继续执行,判断当前是否有继续执行的函数有的话就继续执行并改变其this指向
                    return this.success && this.success.passRequest.apply(this.success, arguments);
                }
            }
        }

使用

//构造函数结构定金函数创建实例
       var depositamt400 = new Automobile(depositamt400);
        var depositamt200 = new Automobile(depositamt200);
        var orderNormal = new Automobile(orderNormal);
//添加后续根据标记执行函数
        depositamt400.setNextSuccess(depositamt200);
        depositamt200.setNextSuccess(orderNormal);
//使用
        depositamt400.passRequest(10000, 1, 200, true);
        depositamt400.passRequest(10000, 1, 400, true);
        depositamt400.passRequest(10000, 0, 400, true);
        depositamt400.passRequest(10000, 1, 0, false);
        depositamt400.passRequest(10000, 0, 0, false);

职责链设计模式它只需要知道链式中首个节点就可进行操作,因此减弱了发送者和多个接受者之间的联系,但是并不能保证数据一定会被链式节点处理,也不能保证数据会被所有的链式节点处理


坚持努力,无惧未来!

相关文章
|
5月前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 职责链模式
js设计模式【详解】—— 职责链模式
78 8
|
2月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
33 3
|
4月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
59 1
|
4月前
|
设计模式 JavaScript 前端开发
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
|
5月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
83 7
|
5月前
|
设计模式 JavaScript
js设计模式【详解】—— 桥接模式
js设计模式【详解】—— 桥接模式
73 6
|
5月前
|
设计模式 JavaScript
js设计模式【详解】—— 原型模式
js设计模式【详解】—— 原型模式
53 6
|
5月前
|
设计模式 JavaScript 算法
js设计模式【详解】—— 模板方法模式
js设计模式【详解】—— 模板方法模式
48 6
|
5月前
|
设计模式 JavaScript 前端开发
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第7天】在软件工程中,设计模式是解决常见问题的标准解决方案。JavaScript中的工厂模式用于对象创建,但过度使用可能导致抽象过度和缺乏灵活性。单例模式确保唯一实例,但应注意避免全局状态和过度使用。观察者模式实现了一对多依赖,需警惕性能影响和循环依赖。通过理解模式的优缺点,能提升代码质量。例如,工厂模式通过`createShape`函数动态创建对象;单例模式用闭包保证唯一实例;观察者模式让主题对象通知多个观察者。设计模式的恰当运用能增强代码可维护性。
84 0
|
5月前
|
设计模式 缓存 JavaScript
js设计模式实例
【7月更文挑战第2天】JavaScript设计模式包含工厂、单例、建造者、抽象工厂和代理模式等,它们是最佳实践和可重用模板,解决创建、职责分配和通信等问题。例如,工厂模式封装对象创建,单例确保全局唯一实例,建造者模式用于复杂对象构建,抽象工厂创建相关对象集合,而代理模式则控制对象访问。这些模式提升代码质量、可读性和灵活性,是高效开发的关键。
41 0