成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

js設(shè)計(jì)模式--策略模式

bigdevil_s / 2520人閱讀

摘要:將不變的部分和變化的部分隔開(kāi)是每個(gè)設(shè)計(jì)模式的主題,策略模式也不例外,策略模式的目的就是將算法的使用與算法的實(shí)現(xiàn)分離開(kāi)來(lái)。

前言

本系列文章主要根據(jù)《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》整理而來(lái),其中會(huì)加入了一些自己的思考。希望對(duì)大家有所幫助。

文章系列

js設(shè)計(jì)模式--單例模式

js設(shè)計(jì)模式--策略模式

js設(shè)計(jì)模式--代理模式

概念

策略模式的定義是:定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái),并且使它們可以相互替換

策略模式指的是定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái)。將不變的部分和變化的部分隔開(kāi)是每個(gè)設(shè)計(jì)模式的主題,策略模式也不例外,策略模式的目的就是將算法的使用與算法的實(shí)現(xiàn)分離開(kāi)來(lái)。

一個(gè)基于策略模式的程序至少由兩部分組成。第一個(gè)部分是一組策略類(lèi),策略類(lèi)封裝了具體 的算法,并負(fù)責(zé)具體的計(jì)算過(guò)程。 第二個(gè)部分是環(huán)境類(lèi)Context,Context 接受客戶的請(qǐng)求,隨后 把請(qǐng)求委托給某一個(gè)策略類(lèi)。要做到這點(diǎn),說(shuō)明 Context中要維持對(duì)某個(gè)策略對(duì)象的引用。

策略模式的實(shí)現(xiàn)并不復(fù)雜,關(guān)鍵是如何從策略模式的實(shí)現(xiàn)背后,找到封裝變化、委托和多態(tài)性這些思想的價(jià)值。

場(chǎng)景

從定義上看,策略模式就是用來(lái)封裝算法的。但如果把策略模式僅僅用來(lái)封裝算法,未免有一點(diǎn)大材小用。在實(shí)際開(kāi)發(fā)中,我們通常會(huì)把算法的含義擴(kuò)散開(kāi)來(lái),使策略模式也可以用來(lái)封裝 一系列的“業(yè)務(wù)規(guī)則”。只要這些業(yè)務(wù)規(guī)則指向的目標(biāo)一致,并且可以被替換使用,我們就可以 用策略模式來(lái)封裝它們。

優(yōu)缺點(diǎn) 優(yōu)點(diǎn)

策略模式利用組合、委托和多態(tài)等技術(shù)和思想,可以有效地避免多重條件選擇語(yǔ)句。

策略模式提供了對(duì)開(kāi)放—封閉原則的完美支持,將算法封裝在獨(dú)立的strategy中,使得它們易于切換,易于理解,易于擴(kuò)展。

策略模式中的算法也可以復(fù)用在系統(tǒng)的其他地方,從而避免許多重復(fù)的復(fù)制粘貼工作。

在策略模式中利用組合和委托來(lái)讓 Context 擁有執(zhí)行算法的能力,這也是繼承的一種更輕便的替代方案。

缺點(diǎn)

增加許多策略類(lèi)或者策略對(duì)象,但實(shí)際上這比把它們負(fù)責(zé)的 邏輯堆砌在 Context 中要好。

要使用策略模式,必須了解所有的 strategy,必須了解各個(gè) strategy 之間的不同點(diǎn), 這樣才能選擇一個(gè)合適的 strategy。

但這些缺點(diǎn)并不嚴(yán)重

例子 計(jì)算獎(jiǎng)金 粗糙的實(shí)現(xiàn)
    var calculateBonus = function( performanceLevel, salary ){
        if ( performanceLevel === "S" ){
            return salary * 4;
        }
        if ( performanceLevel === "A" ){
            return salary * 3;
        }
        if ( performanceLevel === "B" ){
            return salary * 2;
        }
    };

    calculateBonus( "B", 20000 ); // 輸出:40000
    calculateBonus( "S", 6000 ); // 輸出:24000

缺點(diǎn):

calculateBonus 函數(shù)比較龐大,包含了很多 if-else 語(yǔ)句

calculateBonus 函數(shù)缺乏彈性,如果增加了一種新的績(jī)效等級(jí) C,或者想把績(jī)效 S 的獎(jiǎng)金 系數(shù)改為 5,那我們必須深入 calculateBonus 函數(shù)的內(nèi)部實(shí)現(xiàn),這是違反開(kāi)放?封閉原則的。

算法的復(fù)用性差

使用組合函數(shù)重構(gòu)代碼
    var performanceS = function( salary ){
        return salary * 4;
    };
    var performanceA = function( salary ){
        return salary * 3;
    };
    var performanceB = function( salary ){
        return salary * 2;
    };
    var calculateBonus = function( performanceLevel, salary ){
        if ( performanceLevel === "S" ){
            return performanceS( salary );
        }
        if ( performanceLevel === "A" ){
            return performanceA( salary );
        }
        if ( performanceLevel === "B" ){
            return performanceB( salary );
        }
    };
    calculateBonus( "A" , 10000 ); // 輸出:30000

問(wèn)題依然存在:calculateBonus 函數(shù)有可能越來(lái)越龐大,而且在系統(tǒng)變化的時(shí)候缺乏彈性

使用策略模式重構(gòu)代碼
    var performanceS = function(){};
    performanceS.prototype.calculate = function( salary ){
        return salary * 4;
    };
    var performanceA = function(){};
    performanceA.prototype.calculate = function( salary ){
        return salary * 3;
    };
    var performanceB = function(){};
    performanceB.prototype.calculate = function( salary ){
        return salary * 2;
    };

    //接下來(lái)定義獎(jiǎng)金類(lèi)Bonus:

    var Bonus = function(){
        this.salary = null; // 原始工資
        this.strategy = null; // 績(jī)效等級(jí)對(duì)應(yīng)的策略對(duì)象
    };
    Bonus.prototype.setSalary = function( salary ){
        this.salary = salary; // 設(shè)置員工的原始工資
    };
    Bonus.prototype.setStrategy = function( strategy ){
        this.strategy = strategy; // 設(shè)置員工績(jī)效等級(jí)對(duì)應(yīng)的策略對(duì)象
    };
    Bonus.prototype.getBonus = function(){ // 取得獎(jiǎng)金數(shù)額
        return this.strategy.calculate( this.salary ); // 把計(jì)算獎(jiǎng)金的操作委托給對(duì)應(yīng)的策略對(duì)象
    };

    var bonus = new Bonus();
    bonus.setSalary( 10000 );

    bonus.setStrategy( new performanceS() ); // 設(shè)置策略對(duì)象
    console.log( bonus.getBonus() ); // 輸出:40000
    bonus.setStrategy( new performanceA() ); // 設(shè)置策略對(duì)象
    console.log( bonus.getBonus() ); // 輸出:30000

但這段代碼是基于傳統(tǒng)面向?qū)ο笳Z(yǔ)言的模仿,下面我們用JavaScript實(shí)現(xiàn)的策略模式。

JavaScript 版本的策略模式

在 JavaScript 語(yǔ)言中,函數(shù)也是對(duì)象,所以更簡(jiǎn)單和直接的做法是把 strategy 直接定義為函數(shù)

    var strategies = {
        "S": function( salary ){
            return salary * 4;
        },
        "A": function( salary ){
            return salary * 3;
        },
        "B": function( salary ){
            return salary * 2;

        }
    };
    var calculateBonus = function( level, salary ){
        return strategies[ level ]( salary );
    };

    console.log( calculateBonus( "S", 20000 ) ); // 輸出:80000
    console.log( calculateBonus( "A", 10000 ) ); // 輸出:30000
es6類(lèi)實(shí)現(xiàn)
var performanceS = function () {};
performanceS.prototype.calculate = function (salary) {
  return salary * 4;
};
var performanceA = function () {};
performanceA.prototype.calculate = function (salary) {
  return salary * 3;
};
var performanceB = function () {};
performanceB.prototype.calculate = function (salary) {
  return salary * 2;
};

//接下來(lái)定義獎(jiǎng)金類(lèi)Bonus:
class Bonus {
  constructor() {
    this.salary = null; // 原始工資
  this.strategy = null; // 績(jī)效等級(jí)對(duì)應(yīng)的策略對(duì)象
  }
  setSalary(salary) {
    this.salary = salary; // 設(shè)置員工的原始工資
  }
  setStrategy(strategy) {
    this.strategy = strategy; // 設(shè)置員工績(jī)效等級(jí)對(duì)應(yīng)的策略對(duì)象
  }
  getBonus() { // 取得獎(jiǎng)金數(shù)額
    return this.strategy.calculate(this.salary); // 把計(jì)算獎(jiǎng)金的操作委托給對(duì)應(yīng)的策略對(duì)象
  }
}

var bonus = new Bonus();
bonus.setSalary(10000);

bonus.setStrategy(new performanceS()); // 設(shè)置策略對(duì)象
console.log(bonus.getBonus()); // 輸出:40000
bonus.setStrategy(new performanceA()); // 設(shè)置策略對(duì)象
console.log(bonus.getBonus()); // 輸出:30000
緩動(dòng)動(dòng)畫(huà) 目標(biāo):編寫(xiě)一個(gè)動(dòng)畫(huà)類(lèi)和一些緩動(dòng)算法,讓小球以各種各樣的緩動(dòng)效果在頁(yè)面中運(yùn)動(dòng) 分析:

首先緩動(dòng)算法的職責(zé)是實(shí)現(xiàn)小球如何運(yùn)動(dòng)

然后動(dòng)畫(huà)類(lèi)(即context)的職責(zé)是負(fù)責(zé):

初始化動(dòng)畫(huà)對(duì)象

在運(yùn)動(dòng)開(kāi)始之前,需要提前記錄一些有用的信息,至少包括以下信息:

動(dòng)畫(huà)開(kāi)始時(shí)的準(zhǔn)確時(shí)間點(diǎn);

動(dòng)畫(huà)開(kāi)始時(shí),小球所在的原始位置;

小球移動(dòng)的目標(biāo)位置;

小球運(yùn)動(dòng)持續(xù)的時(shí)間。

計(jì)算小球某時(shí)刻的位置

更新小球的位置

實(shí)現(xiàn):




  
  
  
  Document



  
我是div
驗(yàn)證表單 簡(jiǎn)單的實(shí)現(xiàn)



  
請(qǐng)輸入用戶名: 請(qǐng)輸入密碼: 請(qǐng)輸入手機(jī)號(hào)碼:
使用策略模式改進(jìn)



  
請(qǐng)輸入用戶名: 請(qǐng)輸入密碼: 請(qǐng)輸入手機(jī)號(hào)碼:

缺點(diǎn):一 個(gè)文本輸入框只能對(duì)應(yīng)一種校驗(yàn)規(guī)則

再改進(jìn):可以有多個(gè)校驗(yàn)規(guī)則



  
請(qǐng)輸入用戶名: 請(qǐng)輸入密碼: 請(qǐng)輸入手機(jī)號(hào)碼:

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100630.html

相關(guān)文章

  • JS 設(shè)計(jì)模式 十四(策略模式

    摘要:策略模式定義一系列的算法把它們一個(gè)個(gè)封裝起來(lái)并且使它們可相互替換。策略模式要素策略接口,用來(lái)約束一系列具體的策略算法。策略模式策略購(gòu)買(mǎi)輛總金額策略購(gòu)買(mǎi)輛總金額策略模式優(yōu)點(diǎn)算法可以自由切換。策略模式缺點(diǎn)策略類(lèi)會(huì)增多。所有策略類(lèi)都需要對(duì)外暴露。 策略模式 定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái), 并且使它們可相互替換。本模式使得算法可獨(dú)立于使用它的客戶而變化。策略模式是把一個(gè)類(lèi)中經(jīng)常改變或...

    sutaking 評(píng)論0 收藏0
  • JS策略模式《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》閱讀筆記

    摘要:策略模式可以避免代碼中的多重判斷條件。策略模式在程序中或多或少的增加了策略類(lèi)。此文僅記錄本人閱讀設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐這個(gè)本時(shí)的感受,感謝作者曾探寫(xiě)出這么好的一本書(shū)。設(shè)計(jì)模式中很重要的一點(diǎn)就是將不變和變分離出來(lái)。參考設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐曾探 策略模式的定義是:定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái),并且是它們可以相互替換。 策略模式可以避免代碼中的多重判斷條件。 策略模式很好的體現(xiàn)了開(kāi)放-...

    Amos 評(píng)論0 收藏0
  • JS設(shè)計(jì)模式——策略模式

    摘要:版本策略模式在上個(gè)例子中雖然初步實(shí)現(xiàn)了策略模式,但是是仿照的傳統(tǒng)面向?qū)ο笳Z(yǔ)言,而的實(shí)現(xiàn)更為簡(jiǎn)單,直接把原來(lái)的實(shí)例定義成函數(shù),原先的類(lèi)用函數(shù)來(lái)委托。 1. 介紹 策略模式是JS設(shè)計(jì)模式中一大重要的模式有著廣泛的應(yīng)用 2. 定義 定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái),并且使它們可以相互替換 3. 應(yīng)用 根據(jù)等級(jí)、工資計(jì)算獎(jiǎng)金等類(lèi)似情況、使用不同的動(dòng)畫(huà)效果、表單驗(yàn)證等 4. 思想 把算法實(shí)...

    Jrain 評(píng)論0 收藏0
  • JavaScript 設(shè)計(jì)模式系列 - 策略模式與動(dòng)態(tài)表單驗(yàn)證

    摘要:策略模式又稱(chēng)政策模式,其定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái),并且使它們可以互相替換。的表單具有表單驗(yàn)證功能,用來(lái)校驗(yàn)用戶輸入的表單內(nèi)容。實(shí)際需求中表單驗(yàn)證項(xiàng)一般會(huì)比較復(fù)雜,所以需要給每個(gè)表單項(xiàng)增加自定義校驗(yàn)方法。 showImg(https://segmentfault.com/img/remote/1460000020135990); 策略模式 (Strategy Pattern...

    宋華 評(píng)論0 收藏0
  • JS設(shè)計(jì)模式-策略模式

    摘要:策略模式是指對(duì)一系列的算法定義,并將每一個(gè)算法封裝起來(lái),而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。 策略模式是指對(duì)一系列的算法定義,并將每一個(gè)算法封裝起來(lái),而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。 優(yōu)點(diǎn): 策略模式利用組合、委托等技術(shù)和思想,可以避免很多if條件語(yǔ)句 策略模式提供了開(kāi)放-封閉原則,使代碼更容易理解和拓展 簡(jiǎn)單...

    mylxsw 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<