[設計模式] javascript 之 策略模式

策略模式說明算法

定義: 封裝一系列的算法,使得他們之間能夠相互替換,本模式使用算法獨立於使用它的客戶的變化。設計模式

說明:策略模式,是一種組織算法的模式,核心不在於算法,而在於組織一系列的算法,而且如何去使用它;策略模式做用在於,行爲實現的不可預見,面對這樣的一種變化,咱們得思考如何使用程序好維跟擴展,並使得客戶很好的使用算法的方式;this

策略模式 使用要注意它 "變化" 的一面,策略模式就是來解決這個 變化 問題的。編碼

好比商場買賣的價格或促銷問題,若是不使用模式,就可能只是 把「全部」的狀況用 if else 相似「硬編碼」 的開式寫在一塊兒,或是傳個傳個參數,稍加點內部邏輯代碼,最好就是一同寫在一個類裏面;spa

P如:prototype

function Price(personType, price) {
    //大客戶 5 折
    if (personType == 'vip') {
        return price * 0.5;
    } 
    else if (personType == 'old'){ //老客戶 3 折
        return price * 0.3;
    } else {
        return price; //其餘都全價
    }
}

咱們把上面的當作一個類,若是要擴展一種價格手段,就得在 Price 裏添加新的 else if,或是修改某個算法邏輯,就得某個 if 或 else if 裏修改, 這是對單個類的修改,並且這種狀況勢必得常常修改這個類,這違反了設計模式的一個原則:對修改關閉,對擴展開放的原則;設計

並且這些算法,在不一樣客戶面前可能會常常替換,固定參數也不能知足需求;3d

解決這種問題就可使用策略模式,策略在於關注變化,把各行爲不一樣的實現各自封裝起來,好比要實現一隻動物,走路,叫聲,吃東西的各類表現,就能夠把走路,叫聲,吃東西,就能夠定義三個接口抽象,而後把他們各自具體實現去實現三個接口;code

前面說,策略模式是使算法可獨立於使用的客戶的改變,因此策略模式裏,通常是在客戶端定義選擇使用的算法,傳入相應的參數,再根據算法返回結果;blog

策略模式結構圖:

這種有點相似簡單工廠模式,這種再加層 Context 是爲了客戶使用起來更簡單調用,沒必要自處理一些邏輯,讓團隊開發,更趨一致;Context 也能夠作成一個基類,其下能夠有多個實現子類繼承;

Context 跟 Client 能夠改成:

繼承子類只需引用本身的實現接口算法,便可,這樣客戶能夠更簡單的調用,也沒必要理會各類動物使用什麼接口,是怎麼實現的了;

實例源碼 

這裏以上面的商場價格手段來實現:

1. 實現幾種算法,Javascript是弱類型,沒有接口這號東西,就是直接寫了;

vip 客戶

function vipPrice() {
    this.discount = 0.5;
}

vipPrice.prototype.getPrice = function(price) {
  return price * this.discount; }

老客戶:

function oldPrice() {
    this.discount = 0.3;
}

oldPrice.prototype.getPrice = function(price) {
    return price * this.discount;
}

普通客戶

function Price() {
    this.discount = 1;
}

Price.prototype.getPrice = function(price) {
    return price ;
}

2. 上下文:

function Context() {
    this.name = '';
    this.strategy = null;
    this.price = 0;
}

Context.prototype.set = function(name, strategy, price) {
    this.name = name;
    this.strategy = strategy;
    this.price = price;
}

Context.prototype.getResult = function() {
    console.log(this.name + ' 的結帳價爲: ' + this.stragegy.getPrice(this.price));
}

3. 客戶端使用;

// 上下文
var context = new Context();

//vip客戶
var vip = new vipPrice();
context.set ('vip客戶', vip, 200);
context.getPrice();

//老客戶
var old = new oldPrice();
context.set ('老客戶', old, 200);
context.getPrice();

//普通客戶
//...

這樣即便得 客戶 與算法解藕,又使得修改跟擴展能獨立的進行,不影到客戶端或其餘算法的使用;

其餘說明

策略模式是一個很是實用跟經常使用的設計模式,普通用於商場價格,促銷等場景,他跟工廠模式很像,能夠說是他的一種升級版本;

策略模式相關模式:工廠模式,組合模式;

關健字:算法,變化,封裝,上下文;

相關文章
相關標籤/搜索