温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2022-01-11 11:15:40 来源:亿速云 阅读:159 作者:iii 栏目:开发技术

这篇文章主要讲解了“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设计模式中的策略模式怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI