" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

javascript設計模式之策略模式

 更新時間:2022年01月11日 09:10:32   作者:石頭山_S  
這篇文章主要為大家介紹了javascript策略模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

一. 認識策略模式

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

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

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

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

1. 通過分支實現(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;
            }
        }

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

因此我們使用策略模式來重構代碼。

2.使用策略模式實現(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; // 原始績效
        }
        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 分支,減少了性能消耗,并且使代碼有了彈性,隨時增加其他績效,不需要更改原代碼。

主要思想:這段代碼基于面向對象語言,引入了多態(tài)的概念,不適用于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 的對象可以直接創(chuàng)建,將函數封裝進去,這樣一來,代碼顯得清晰簡潔。代碼的復用,彈性也隨之變強。

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

三. 策略模式的實際運用

1. 使用策略模式實現(xiàn)緩存動畫

        // 緩動算法
        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 節(jié)點
        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);
        }
 
        // 實現(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. 使用策略模式進行表單驗證

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

分析:第一個實現(xiàn)中是把緩動算法封裝在一個對象中,調用他們時便于相互替換,也便于擴展。

第二個實現(xiàn)是將校驗規(guī)則封裝起來。

四. 總結

策略模式利用組合、委托、多態(tài)等技術思想,有效避免多重條件選擇語句,將算法封裝在 strategy 中,使他們易于切換、擴展。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • 利用javascript數組長度循環(huán)數組內所有元素

    利用javascript數組長度循環(huán)數組內所有元素

    javascript循環(huán)數組內所有元素代碼學習,大家參考使用吧
    2013-12-12
  • JS中for循序中延遲加載動態(tài)效果的具體實現(xiàn)

    JS中for循序中延遲加載動態(tài)效果的具體實現(xiàn)

    今天在做一個前端的效果的時候碰到一個棘手的問題,就是實現(xiàn)一個動態(tài)的圓柱效果,廢話不多少,直接上代碼
    2013-08-08
  • JavaScript中對DOM節(jié)點的訪問、創(chuàng)建、修改、刪除

    JavaScript中對DOM節(jié)點的訪問、創(chuàng)建、修改、刪除

    這篇文章主要介紹了JavaScript中對DOM節(jié)點的訪問、創(chuàng)建、修改、刪除,是JavaScript入門學習中的基礎知識,需要的朋友可以參考下
    2015-11-11
  • 控制臺報錯object is not a function的解決方法

    控制臺報錯object is not a function的解決方法

    頁面的功能用不了,打開控制臺發(fā)現(xiàn)報錯:object is not a function,下面是原因與解決方法,有類似情況的朋友可以看看
    2014-08-08
  • 淺談JavaScript數據類型

    淺談JavaScript數據類型

    本文從javascript的數據類型的簡介開始談起,接著講述了javascript的6種數據類型,分別為Number、Boolean、String、Null、Undefined和Object,并給出了一個typeof操作符的示例,這里分享給大家。
    2015-03-03
  • 前端面試題及答案整理(二)

    前端面試題及答案整理(二)

    上一篇從常見數據結構算法、JavaScript兩個方面從面試的角度進行了整理,本文將對其余內容進行補充
    2016-08-08
  • javascript之Array 數組對象詳解

    javascript之Array 數組對象詳解

    本文主要是對javascript之Array 數組對象的詳解 ,比較詳細,希望能給大家做一個參考。
    2016-06-06
  • 詳細談談javascript的對象

    詳細談談javascript的對象

    對象是一種復合值,它將很多值(原始值或其他對象)聚合在一起,可通過屬性名訪問這些值。而屬性名可以是包含空字符串在內的任意字符串。JavaScript對象也可以稱作一種數據結構
    2016-07-07
  • JavaScript中的對象與JSON

    JavaScript中的對象與JSON

    這篇文章主要介紹了JavaScript中的對象與JSON,本文講解了定義JSON與javascript對象、javascript對象轉換為JSON、javascript中解析JSON等內容,需要的朋友可以參考下
    2015-07-07
  • JavaScript的函數式編程基礎指南

    JavaScript的函數式編程基礎指南

    這篇文章主要介紹了JavaScript的函數式編程基礎指南,雖然JavaScript被許多人一再強調面向對象,但js中卻沒有類,而本文所展現(xiàn)的函數主導的js編程則同樣可以很爽,需要的朋友可以參考下
    2016-03-03

最新評論

峨眉山市| 望都县| 玉树县| 兴义市| 苍梧县| 黄骅市| 松溪县| 巧家县| 金门县| 蓬溪县| 陈巴尔虎旗| 新宾| 樟树市| 凤庆县| 图片| 大同县| 太仆寺旗| 扶沟县| 定州市| 莒南县| 会东县| 思茅市| 赣州市| 界首市| 资源县| 恩平市| 金堂县| 宁陵县| 钟祥市| 洛宁县| 恩施市| 淮阳县| 平邑县| 全州县| 辽阳市| 关岭| 大方县| 南部县| 德兴市| 鄂伦春自治旗| 霍邱县|