千家信息网

javascript设计模式中的策略模式怎么实现

发表于:2024-11-13 作者:千家信息网编辑
千家信息网最后更新 2024年11月13日,这篇文章主要讲解了"javascript设计模式中的策略模式怎么实现",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"javascript设计模式中的策略
千家信息网最后更新 2024年11月13日javascript设计模式中的策略模式怎么实现

这篇文章主要讲解了"javascript设计模式中的策略模式怎么实现",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"javascript设计模式中的策略模式怎么实现"吧!

一. 认识策略模式

策略模式的定义:定义一系列的算法,将他们一个个封装起来,使他们直接可以相互替换。

策略模式是开发中常用的第二种设计模式,它在开发中非常常见,由两部分组成。第一部分是策略类,封装了许多具体的,相似的算法。第二部分是环境类,接受客户请求,随后将请求委托给策略类。说的通俗一点就是将相同算法的函数存放在一个包装里边,每个函数用相同的方式拿出来,就叫做策略模式。下面我们来通过代码实现深入了解一下。

二. 具体实现和思想

假如需要实现一个计算员工奖金的程序,效绩为 S 则发基本工资的4倍,A 则3倍,以此类推,那么我们正常实现该代码,是通过判断分支语句来实现。

1. 通过分支实现

        let bonus = function (performance, salary) {            if(performance === "S") {                return salary*4;            }            if(performance === "A") {                return salary*3;            }            if(performance === "B") {                return salary*2;            }        }

分析:该实现存在显著的缺点,如果随着效绩 的扩展,比如增加C,D,E, if 分支不断累加,使得代码越来越庞大。

因此我们使用策略模式来重构代码。

2.使用策略模式实现

        let performanceS = function () {};        performanceS.prototype.calculate = function ( salary ) {            return salary*4        }        let performanceA = function () {};        performanceA.prototype.calculate = function ( salary ) {            return salary*3        }        let performanceB = function () {};        performanceB.prototype.calculate = function ( salary ) {            return salary*2        }        let performanceC = function () {};        performanceC.prototype.calculate = function ( salary ) {            return salary*1        }         let Bonus = function () {            this.salary = null; // 原始工资            this.strategy = null; // 原始绩效        }        Bonus.prototype.setSalary = function ( salary ) {            this.salary = salary;        }        Bonus.prototype.setStrategy = function ( strategy ) {            this.strategy = strategy;        }        Bonus.prototype.getBonus = function () {            if(!this.strategy) {                throw new Error("未设置绩效");            }            return this.strategy.calculate(this.salary);        }         let bonus = new Bonus();        bonus.setSalary(10000);        bonus.setStrategy(new performanceS());        console.log(bonus.getBonus());

分析:重构后,我们将每种绩效算法单独成一个函数,需要计算某种绩效时只需要将其传入 getBonus 函数中,去掉了 if 分支,减少了性能消耗,并且使代码有了弹性,随时增加其他绩效,不需要更改原代码。

主要思想:这段代码基于面向对象语言,引入了多态的概念,不适用于js。

3. JavaScript 版本的策略模式

        // js中函数也是对象,直接将 strategy 定义为函数        let strategy = {            "S": function ( salary ){                return salary*4;            },            "A": function ( salary ) {                return salary*3;            },            "B": function ( salary ) {                 return salary*2;            }        }        let calculateBonus = function ( level, salary ) {            return strategy[ level ]( salary );        }        console.log(calculateBonus('A', 20000)) // 6000

分析:js 的对象可以直接创建,将函数封装进去,这样一来,代码显得清晰简洁。代码的复用,弹性也随之变强。

以上就是 js 设计模式策略模式的主要思想和实现,他在应用中有两个主要的作用,一是策略模式实现晃动动画;二是实现表单验证,有能力有兴趣的小伙伴可以往下看。

三. 策略模式的实际运用

1. 使用策略模式实现缓存动画

        // 缓动算法        let tween = {            linear (t, b, c, d) {                return c*t/d + b;            },            easeIn (t, b, c, d) {                return c*(t /= d) *t + b;            },            strongEaseIn (t, b, c, d) {                return c*(t /= d) *t *t *t *t + b;            }        }         // 定义一个动画类,参数为要运动的 dom 节点        let Animate = function ( dom ) {            this.dom = dom;            this.startTime = 0;            this.startPos = 0;            this.endPos = 0;            this.propertyName = null;            this.easing = null; // 缓动算法            this.duration = null;        }         // 启动方法        Animate.prototype.start = function (propertyName, endPos, duration, easing) {            this.startTime =+ new Date;            this.startPos = this.dom.getBoundingClientRect()[propertyName]; // dom 初始位置            this.propertyName = propertyName;            this.endPos = endPos;            this.duration = duration;            this.easing = tween[easing];             let self = this;            let timeId = setInterval(() => {                if( self.step() === false){                    clearInterval(timeId);                }            }, 19);        }         // 实现小球每一帧要做的事情        Animate.prototype.step = function () {            let t =+ new Date;            if(t>this.startTime + this.duration){                this.update(this.endPos);                return false;            }            let pos = this.easing(t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration);            this.update(pos);        }         Animate.prototype.update = function (pos) {            this.dom.style[this.propertyName] = pos + 'px';        }         let test = function () {            let div = document.getElementById('div');            let animate = new Animate(div);            animate.start('left', 500, 1000, 'strongEaseIn');            // animate.start('top', 1500,  500, 'strongEaseIn');        }        test();

2. 使用策略模式进行表单验证

        let strategies = {            isNonEmpty ( value, errorMsg) { // 判断是否为空                if(value === '') {                    return errorMsg;                }            },            minLength (value, length, errorMsg){                if (value.length < length) {                    return errorMsg;                }            }        }         let dom = document.forms[0].acount;         let validatarFunc = function () {            let validator = new Validator();            // 添加校验规则            validator.add(dom, 'isNonEmpty', '用户名不能为空!');            let errorMsg = validator.start();            return errorMsg; // 返回校验结果        }                 // 实现表单校验保存类        let Validator = function () {            this.cache = []; // 保存校验规则        }        Validator.prototype.add = function (dom, rule, errorMsg) {            let ary = rule.split(':');            this.cache.push( function(){                let strategy = ary.shift();                ary.unshift(dom.value);                ary.push( errorMsg );                return strategies[strategy].apply(dom, ary);            })        }        Validator.prototype.start = function () {            for(let i = 0, validatorFunc; validatorFunc = this.cache[i++];){                let msg = validatorFunc();                if( msg ) {                    return msg;                }            }        }         document.forms[0].addEventListener('submit', (e) =>{            let errorMsg = validatarFunc();            if(errorMsg){                alert(errorMsg);                e.preventDefault();            }        })

分析:第一个实现中是把缓动算法封装在一个对象中,调用他们时便于相互替换,也便于扩展。

第二个实现是将校验规则封装起来。

感谢各位的阅读,以上就是"javascript设计模式中的策略模式怎么实现"的内容了,经过本文的学习后,相信大家对javascript设计模式中的策略模式怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

模式 策略 代码 函数 算法 设计模式 设计 绩效 封装 分支 对象 分析 动画 就是 思想 学习 验证 原始 相同 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发高级需要数学好 架设网单客户端连接不了服务器 文献检索网站和数据库是什么意思 关系型数据库和非关系型数据库的区别 深圳门禁软件开发怎么收费 网络安全的三大技术 阿里数据库技术分享 网络安全从我做起手抄报 微信小程序登录的服务器地址 网络安全色矩阵 郑州物流软件开发如何收费 什么数据库可以在安卓手机使用 数据库教学理论 二道区智能网络技术排名靠前 如何测试本地到服务器的延迟 中国互联网科技公司聚集地 数据库安全诊断系统 尼日利亚网络安全中心 北京金蕴萌网络技术 合肥oa软件开发 数据库 维度 摩登时代下载软件开发 松江区企业网络技术服务口碑推荐 通信网络技术湖南省技能竞赛 流放之路数据库 旋风斩 上海防水网络技术 宁夏银川软件开发哪家靠谱 传奇私服1.45经典服务器 数据库中数据定义实验报告 查询数据库的ip
0