完成一項任務往往有多種方式,我們將其稱之為策略。
比如,超市做活動,如果你的購物積分滿1000,就可以按兌換現金抵用券10元,如果購買同一商品滿10件,就可以打9折,如果如果購買的金額超過500,就可以享受滿減50元的優惠。這是三個不同的**策略。
再比如,去外出旅遊,我們可以選擇火車,也可以選擇公共汽車,可以選擇飛機,也可以選擇自駕遊。這又是四個不同的出行策略。
以上這些真實場景,都有策略選擇模型的影子,可以考慮使用策略模式。
經典的策略模式,是由三部分組成
context:上下文環境類
stragety:策略基類
concretestragety:具體策略
以第乙個超市做活動的場景來舉個例子。
context:order類,訂單資訊,包括商品,**和數量,以為購買者等
stragety:promotion類,抽象基類,包含乙個抽象方法(計算折扣)
contretestragety:分三個類,fidelitypromo,bulkitempromo,largeorderpromo,實現具體的折扣計算方法。
首先是 order 類:
然後是積分兌換現金券的策略,為了保證我們的**具有良好的可擴充套件性及維護性,我會先寫乙個策略類,它是乙個抽象基類,它的子類都是乙個具體的策略,都必須實現 discount 方法,就比如咱們的積分兌換現金策略。
假設現在小明去商場買了一件衣服(600塊),兩雙鞋子(200*2),他的購物積分有1500點。
在平時,商場一般都沒有活動,但是長年都有積分換現金抵用券的活動。
眼看著,五一節也快了,商場準備大搞**
只要單項商品購買10件,即可9折。
如果訂單總金額大於等於500,就可以立減50。
有了此前我們使用 策略模式 打下的基礎,我們並不是使用硬編碼的方式來配置策略,所以不需要改動太多的原始碼,只要直接定義五一節的兩個**策略類即可(同樣繼承自 promotion 抽象基類),就像外掛程式一樣,即插即用。
看到商場活動如此給力,小明的錢包也鼓了起來,開始屯起了生活用品。
如果使用了第乙個策略,原價600,只需要花 580
如果使用了第二個策略,原價600,只需要花550
兩個策略即插即用,只需要在前台下訂單時,選擇對應的策略即可,原業務邏輯無需改動。
但是問題很快又來了,商場搞活動,卻讓顧客手動選擇使用哪個優惠策略,作為乙個良心的商家,應該要能自動對比所有策略得出最優惠的**來給到顧客。這就要求後台**要能夠找出當前可用的全部策略,並一一比對折扣。
在前台下訂單的時候,就會自動計算所有的優惠策略,直接告訴顧客最便宜的**。
通過以上例子,可以總結出使用策略模式的好處
擴充套件性優秀,移植方便,使用靈活。可以很方便擴充套件策略;
各個策略可以自由切換。這也是依賴抽象類設計介面的好處之一;
但同時,策略模式 也會帶來一些弊端。
專案比較龐大時,策略可能比較多,不便於維護;
策略的使用方必須知道有哪些策略,才能決定使用哪乙個策略,這與迪公尺特法則是相違背的。
對於以上的例子,仔細一想,其實還有不少可以優化的地方。
比如,為了實現經典的模式,我們先要定義乙個抽象基類,再實現具體的策略類。對於上面這樣乙個簡單的計算折扣**邏輯來說,其實可以用函式來實現,然後在例項化 order 類時指定這個策略函式即可,大可不必將類給搬出來。這樣就可以避免在下訂單時,不斷的建立策略物件,減少多餘的執行時消耗。這裡就不具體寫出**了。
所以學習設計模式,不僅要知道如何利用這樣的模式組織**,更要領會其思想,活學活用,靈活變通。
python經典案例 Python遞迴的經典案例
目錄 一 遞迴的簡介 二 遞迴的經典應用 2.1 遞迴求階乘 2.2 遞迴推斐波那契數列 2.3 二分法找有序列表指定值 2.4 遞迴解漢諾塔 前言 當我們碰到諸如需要求階乘或斐波那契數列的問題時,使用普通的迴圈往往比較麻煩,但如果我們使用遞迴時,會簡單許多,起到事半功倍的效果。這篇文章主要和大家分...
Python經典案例 身體指數BMI
相信大家都知道bmi 即 bmi 體重 kg 身高2 m2 對於這個問題,我們要做到 calbmiv1.py height,weight eval input 請輸入身高 公尺 和體重 公斤 逗號隔開 bmi weight pow height,2 print bmi 數值為 format bmi ...
Python小爬蟲 案例詳解
python爬取 指定內容 下面的 中有詳細注釋,每個方法下都有解釋說明方法的用途,包括 coding utf 8 引入用於爬蟲的乙個包urllib2 import urllib2 引入正規表示式的包 import re def loadpage url 對爬蟲進行偽裝,並爬取乙個頁面的所有內容 瀏...