首頁  >  文章  >  web前端  >  設計模式的策略模式如何在前端使用

設計模式的策略模式如何在前端使用

php中世界最好的语言
php中世界最好的语言原創
2018-05-24 09:50:301314瀏覽

這次帶給大家設計模式策略模式怎樣在前端使用,設計模式的策略模式在前端使用注意事項有哪些,下面就是實戰案例,一起來看看。

什麼是策略模式?在

GoF四兄弟的經典《設計模式》中,對策略模式的定義如下:

定義一系列的演算法,把它們一個個封裝起來,並且使它們可互相替換。

上邊這句話,從字面來看很簡單。但是如何在開發過程中應用,僅憑一個定義依然是一頭霧水。以筆者曾經做過的商家進銷存系統為例:

某家超市準備舉辦促銷活動,市場人員經過調查分析制定了一些促銷策略:
  1. 購物滿100減10

  2. 購物滿200減30

  3. 購物滿300減50

  4. # #。 。 。

收銀軟體的介面是這樣的(簡單示意):設計模式的策略模式如何在前端使用

我們該如何計算實際消費金額?

最初的實作是這樣的:<pre class="brush:php;toolbar:false">//方便起见,我们把各个促销策略定义为枚举值:0,1,2... var getActualTotal = function(onSaleType,originTotal){     if(onSaleType===0){         return originTotal-Math.floor(originTotal/100)*10     }     if(onSaleType===1){         return originTotal-Math.floor(originTotal/200)*30     }     if(onSaleType===0){         return originTotal-Math.floor(originTotal/300)*50     } } getActualTotal(1,2680); //2208</pre>上面這段程式碼很簡單,而且缺點也很明顯。隨著我的滿減策略逐漸增多,getActualTotal函數會越變越大,而且充滿了

if

判斷,稍一疏忽就容易弄錯。

OK,有人說我很懶,雖然這樣不夠優雅但不影響我的使用,畢竟滿減策略再多也多不到哪裡去。
我只能說,需求永遠不是程式設計師定的。 。這時,市場人員說我們新版程式加入了會員功能,我們需要支援以下的促銷策略:
    會員促銷策略:
  1. 會員充300回60,且首單打9折
  2. 會員充500返100,且首單打8折
  3. 會員充1000回300,且首單打7折疊
  4. ...

這個時候,如果你還在原先的getActualTotal函數中繼續加上

if

判斷,我想如果你的領導者review你這段程式碼,可能會懷疑自己當初怎麼把你招進來。 。

OK,我們終於下定決心要重構促銷策略的程式碼,我們可以這麼做:

var vipPolicy_0=function(originTotal){
    return originTotal-Math.floor(originTotal/100)*10
}
var vipPolicy_1=function(originTotal){
    return originTotal-Math.floor(originTotal/200)*30
}
...
//会员充1000返300
var vipPolicy_10=function(account,originTotal){
    if(account===0){
        account+=1300;
        return originTotal*0.9
    }else{
        account+=1300;
        return originTotal;
    }
    return originTotal-Math.floor(originTotal/200)*30
}
...
var vipPolicy_n=function(){
    ...
}
var getActualTotal=function(onSaleType,originTotal,account){
    switch(onSaleType){
        case 0:
            return vipPolicy_0(originTotal);
        case 1:
            return vipPolicy_0(originTotal);
        ...
        case n:
            return ...
        default:
            return originTotal;
    }
}
    好了,現在我們每種策略都有自己獨立的空間了,看起來井井有條。但還有兩個問題沒有解決:
  1. 隨著促銷策略的增加,

    getActualTotal
  2. 的程式碼量依然會越來越大
  3. #系統缺乏彈性,如果需要增加一種策略,那麼除了加入一個策略函數,還需要修改

    switch...case..
  4. 語句

讓我們再來回顧一下策略模式的定義:

定義一系列的演算法,把它們一個個封裝起來,並且使它們可互相替換

在我們的例子中,每種促銷策略的實現方式是不一樣的,但我們最終的目的都是為了求實際金額。策略模式可以把我們對促銷策略的演算法一個個封裝起來,並且使它們可互相替換而不影響我們對實際金額的求值,這正好是我們所需要的。

下面我們用策略模式來重構上面的程式碼:<pre class="brush:php;toolbar:false">var policies={     &quot;Type_0&quot;:function(originTotal){         return originTotal-Math.floor(originTotal/100)*10      },     &quot;Type_1&quot;:function(originTotal){         return originTotal-Math.floor(originTotal/200)*30      },     ...     &quot;Type_n&quot;:function(originTotal){         ...      } } var getActualTotal=function(onSaleType,originTotal,account){     return policies[&quot;Type_&quot;+onSaleType](originTotal,account) } //执行 getActualTotal(0,2680.00);//2208</pre>分析上面的程式碼我們發現,不管促銷策略如何增加,

getActualTotal

函數完全不需要再變化了。我們要做的,就是增加新策略的函數而已。 透過策略模式的程式碼,我們消除了讓人反胃的大片條件分支語句,

getActualTotal

本身並沒有計算能力,而是將計算全權委託給了策略函數。

    由此我們可以總結出策略模式實現的要點:
  1. ###將變化的演算法封裝成獨立的策略函數,並負責具體的計算####
  2. 委託函數,函數接受客戶請求,並將請求委託給某一個具體的策略函數

以UML圖表示如下:
設計模式的策略模式如何在前端使用

怎麼樣?現在看到上面這張圖是不是有了然於胸部的感覺?那就趕快去試試策略模式吧!


參考書籍:

  1. 《設計模式:可重複使用物件導向軟體的基礎》

  2. 《大話設計模式》

  3. #《Javascript設計模式與開發實踐》

做前端開發已經好幾年了,對設計模式一直沒有深入學習總結過。隨著架構相關的工作越來越多,越來越能感覺到設計模式成為了我前進道路上的阻礙。所以從今天開始深入學習和總結經典的設計模式以及物件導向的幾大原則。

今天第一天,首先來講策略模式。

什麼是策略模式?在

GoF四兄弟的經典《設計模式》中,對策略模式的定義如下:

定義一系列的演算法,把它們一個個封裝起來,並且使它們可互相替換。

上邊這句話,從字面來看很簡單。但是如何在開發過程中應用,僅憑一個定義依然是一頭霧水。以筆者曾經做過的商家進銷存系統為例:

某家超市準備舉辦促銷活動,市場人員經過調查分析制定了一些促銷策略:
  1. 購物滿100減10

  2. 購物滿200減30

  3. 購物滿300減50

  4. # #。 。 。

收銀軟體的介面是這樣的(簡單示意):設計模式的策略模式如何在前端使用

我們該如何計算實際消費金額?

最初的實作是這樣的:<pre class="brush:php;toolbar:false">//方便起见,我们把各个促销策略定义为枚举值:0,1,2... var getActualTotal = function(onSaleType,originTotal){     if(onSaleType===0){         return originTotal-Math.floor(originTotal/100)*10     }     if(onSaleType===1){         return originTotal-Math.floor(originTotal/200)*30     }     if(onSaleType===0){         return originTotal-Math.floor(originTotal/300)*50     } } getActualTotal(1,2680); //2208</pre>上面這段程式碼很簡單,而且缺點也很明顯。隨著我的滿減策略逐漸增多,getActualTotal函數會越變越大,而且充滿了

if

判斷,稍一疏忽就容易弄錯。

OK,有人說我很懶,雖然這樣不夠優雅但不影響我的使用,畢竟滿減策略再多也多不到哪裡去。
我只能說,需求永遠不是程式設計師定的。 。這時,市場人員說我們新版程式加入了會員功能,我們需要支援以下的促銷策略:
    會員促銷策略:
  1. 會員充300回60,且首單打9折
  2. 會員充500返100,且首單打8折
  3. 會員充1000回300,且首單打7折疊
  4. ...

這個時候,如果你還在原先的getActualTotal函數中繼續加上

if

判斷,我想如果你的領導者review你這段程式碼,可能會懷疑自己當初怎麼把你招進來。 。

OK,我們終於下定決心要重構促銷策略的程式碼,我們可以這麼做:

var vipPolicy_0=function(originTotal){
    return originTotal-Math.floor(originTotal/100)*10
}
var vipPolicy_1=function(originTotal){
    return originTotal-Math.floor(originTotal/200)*30
}
...
//会员充1000返300
var vipPolicy_10=function(account,originTotal){
    if(account===0){
        account+=1300;
        return originTotal*0.9
    }else{
        account+=1300;
        return originTotal;
    }
    return originTotal-Math.floor(originTotal/200)*30
}
...
var vipPolicy_n=function(){
    ...
}
var getActualTotal=function(onSaleType,originTotal,account){
    switch(onSaleType){
        case 0:
            return vipPolicy_0(originTotal);
        case 1:
            return vipPolicy_0(originTotal);
        ...
        case n:
            return ...
        default:
            return originTotal;
    }
}
    好了,現在我們每種策略都有自己獨立的空間了,看起來井井有條。但還有兩個問題沒有解決:
  1. 隨著促銷策略的增加,

    getActualTotal
  2. 的程式碼量依然會越來越大
  3. #系統缺乏彈性,如果需要增加一種策略,那麼除了加入一個策略函數,還需要修改

    switch...case..
  4. 語句

###讓我們再來回顧一下策略模式的定義:###
定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换

在我们的例子中,每种促销策略的实现方式是不一样的,但我们最终的目的都是为了求得实际金额。策略模式可以把我们对促销策略的算法一个个封装起来,并且使它们可互相替换而不影响我们对实际金额的求值,这正好是我们所需要的。

下面我们用策略模式来重构上面的代码:

<pre class="brush:php;toolbar:false">var policies={     &quot;Type_0&quot;:function(originTotal){         return originTotal-Math.floor(originTotal/100)*10      },     &quot;Type_1&quot;:function(originTotal){         return originTotal-Math.floor(originTotal/200)*30      },     ...     &quot;Type_n&quot;:function(originTotal){         ...      } } var getActualTotal=function(onSaleType,originTotal,account){     return policies[&quot;Type_&quot;+onSaleType](originTotal,account) } //执行 getActualTotal(0,2680.00);//2208</pre>

分析上面的代码我们发现,不管促销策略如何增加,getActualTotal函数完全不需要再变化了。我们要做的,就是增加新策略的函数而已。

通过策略模式的代码,我们消除了让人反胃的大片条件分支语句,getActualTotal本身并没有计算能力,而是将计算全权委托给了策略函数。

由此我们可以总结出策略模式实现的要点:

  1. 将变化的算法封装成独立的策略函数,并负责具体的计算

  2. 委托函数,该函数接受客户请求,并将请求委托给某一个具体的策略函数

用一张UML图表示如下:
設計模式的策略模式如何在前端使用

怎么样?现在看到上面这张图是不是有了了然于胸的感觉?那就赶紧去试一试策略模式吧!

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样使用JS+H5实现微信摇一摇

如何对微信小程序进行开发

以上是設計模式的策略模式如何在前端使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn