溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

javascript設(shè)計(jì)模式中的策略模式怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2022-01-11 11:15:40 來(lái)源:億速云 閱讀:113 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“javascript設(shè)計(jì)模式中的策略模式怎么實(shí)現(xiàn)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“javascript設(shè)計(jì)模式中的策略模式怎么實(shí)現(xiàn)”吧!

一. 認(rèn)識(shí)策略模式

策略模式的定義:定義一系列的算法,將他們一個(gè)個(gè)封裝起來(lái),使他們直接可以相互替換。

策略模式是開(kāi)發(fā)中常用的第二種設(shè)計(jì)模式,它在開(kāi)發(fā)中非常常見(jiàn),由兩部分組成。第一部分是策略類,封裝了許多具體的,相似的算法。第二部分是環(huán)境類,接受客戶請(qǐng)求,隨后將請(qǐng)求委托給策略類。說(shuō)的通俗一點(diǎn)就是將相同算法的函數(shù)存放在一個(gè)包裝里邊,每個(gè)函數(shù)用相同的方式拿出來(lái),就叫做策略模式。下面我們來(lái)通過(guò)代碼實(shí)現(xiàn)深入了解一下。

二. 具體實(shí)現(xiàn)和思想

假如需要實(shí)現(xiàn)一個(gè)計(jì)算員工獎(jiǎng)金的程序,效績(jī)?yōu)?S 則發(fā)基本工資的4倍,A 則3倍,以此類推,那么我們正常實(shí)現(xiàn)該代碼,是通過(guò)判斷分支語(yǔ)句來(lái)實(shí)現(xiàn)。

1. 通過(guò)分支實(shí)現(xiàn)

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

分析:該實(shí)現(xiàn)存在顯著的缺點(diǎn),如果隨著效績(jī) 的擴(kuò)展,比如增加C,D,E, if 分支不斷累加,使得代碼越來(lái)越龐大。

因此我們使用策略模式來(lái)重構(gòu)代碼。

2.使用策略模式實(shí)現(xiàn)

        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; // 原始績(jī)效
        }
        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("未設(shè)置績(jī)效");
            }
            return this.strategy.calculate(this.salary);
        }
 
        let bonus = new Bonus();
        bonus.setSalary(10000);
        bonus.setStrategy(new performanceS());
        console.log(bonus.getBonus());

分析:重構(gòu)后,我們將每種績(jī)效算法單獨(dú)成一個(gè)函數(shù),需要計(jì)算某種績(jī)效時(shí)只需要將其傳入 getBonus 函數(shù)中,去掉了 if 分支,減少了性能消耗,并且使代碼有了彈性,隨時(shí)增加其他績(jī)效,不需要更改原代碼。

主要思想:這段代碼基于面向?qū)ο笳Z(yǔ)言,引入了多態(tài)的概念,不適用于js。

3. JavaScript 版本的策略模式

        // js中函數(shù)也是對(duì)象,直接將 strategy 定義為函數(shù)
        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 的對(duì)象可以直接創(chuàng)建,將函數(shù)封裝進(jìn)去,這樣一來(lái),代碼顯得清晰簡(jiǎn)潔。代碼的復(fù)用,彈性也隨之變強(qiáng)。

以上就是 js 設(shè)計(jì)模式策略模式的主要思想和實(shí)現(xiàn),他在應(yīng)用中有兩個(gè)主要的作用,一是策略模式實(shí)現(xiàn)晃動(dòng)動(dòng)畫(huà);二是實(shí)現(xiàn)表單驗(yàn)證,有能力有興趣的小伙伴可以往下看。

三. 策略模式的實(shí)際運(yùn)用

1. 使用策略模式實(shí)現(xiàn)緩存動(dòng)畫(huà)

        // 緩動(dòng)算法
        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;
            }
        }
 
        // 定義一個(gè)動(dòng)畫(huà)類,參數(shù)為要運(yùn)動(dòng)的 dom 節(jié)點(diǎn)
        let Animate = function ( dom ) {
            this.dom = dom;
            this.startTime = 0;
            this.startPos = 0;
            this.endPos = 0;
            this.propertyName = null;
            this.easing = null; // 緩動(dòng)算法
            this.duration = null;
        }
 
        // 啟動(dòng)方法
        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);
        }
 
        // 實(shí)現(xiàn)小球每一幀要做的事情
        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. 使用策略模式進(jìn)行表單驗(yàn)證

        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();
            // 添加校驗(yàn)規(guī)則
            validator.add(dom, 'isNonEmpty', '用戶名不能為空!');
            let errorMsg = validator.start();
            return errorMsg; // 返回校驗(yàn)結(jié)果
        }
        
 
        // 實(shí)現(xiàn)表單校驗(yàn)保存類
        let Validator = function () {
            this.cache = []; // 保存校驗(yàn)規(guī)則
        }
        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();
            }
        })

分析:第一個(gè)實(shí)現(xiàn)中是把緩動(dòng)算法封裝在一個(gè)對(duì)象中,調(diào)用他們時(shí)便于相互替換,也便于擴(kuò)展。

第二個(gè)實(shí)現(xiàn)是將校驗(yàn)規(guī)則封裝起來(lái)。

感謝各位的閱讀,以上就是“javascript設(shè)計(jì)模式中的策略模式怎么實(shí)現(xiàn)”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)javascript設(shè)計(jì)模式中的策略模式怎么實(shí)現(xiàn)這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI