首页 > 作文

javascript设计模式之策略模式

更新时间:2023-04-04 13:45:08 阅读: 评论:0

目录
一. 认识策略模式二. 具体实现和思想三. 策略模式的实际运用四. 总结

一. 认识策略模式

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

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

二. 具体实现和思想

假如需要实现一个计算员工奖金的程序,效绩为 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.tsalary = function ( salary ) {            this.salary = salary;        }        bonus.prototype.tstrategy = 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.tsalary(10000);        bonus.tstrategy(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;            },            eain (t, b, c, d) {                return c*(t /= d) *t + b;            },            strongeain (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 lf = this;            let timeid = tinterval(() => {                if( lf.step() === fal){                    clearinterval(timeid);                }            }, 19);        }         // 实现小球每一帧要做的事情        animate.prototype.step = function () {            let t =+ new date;            if(t>this.starttime + this.duration){                this.update(this.endpos);                return fal;            }            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, 'strongeain');            // animate.start('top', 1500,  500, 'strongeain');        }        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, error预科班什么意思msg) {            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 = f篮球计分表unction () {            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();            }        })

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

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

四. 总结

策略模式利用组合、委托、多态等技术思想,有效避免多重条件选择语句,将算法封装在 strategy 中,使他们易于切换、扩展。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注www.887551.com的更多内容!

本文发布于:2023-04-04 13:45:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/0c0804479b122e24ac595eabe70d9daa.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:javascript设计模式之策略模式.doc

本文 PDF 下载地址:javascript设计模式之策略模式.pdf

标签:策略   模式   算法   代码
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图