一、說明
策略模式是一種行為設計模式,它定義了一系列算法,將每個算法封裝起來,并使它們可以互相替換。
(一) 解決問題
在需要根據不同情況選擇不同算法或策略,規避不斷開發新需求后,代碼變得非常臃腫難以維護管理。
(二) 使用場景
- 當一個類有多個行為,而且這些行為在不同的情況下有不同的實現時
- 當需要在運行時動態地選擇算法時
- 當一個類的一部分行為是固定的,一部分是可變的時,可以使用策略模式來封裝可變的部分
二、結構
- 上下文(Context)維護指向具體策略的引用,且僅通過策略接口與該對象進行交流。
- 策略(Strategy)接口是所有具體策略的通用接口,它聲明了一個上下文用于執行策略的方法。
- 具體策略(ConcreteStrategies)實現了上下文所用算法的各種不同變體。
- 當上下文需要運行算法時,它會在其已連接的策略對象上調用執行方法。上下文不清楚其所涉及的策略類型與算法的執行方式。
- 客戶端(Client)會創建一個特定策略對象并將其傳遞給上下文。上下文則會提供一個設置器以便客戶端在運行時替換相關聯的策略。
三、偽代碼
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
策略模式例:商場優惠活動,選擇不同的優惠策略,最后計算的價格也不同。而如果增加新算法,只需增加一個策略類,無需修改現有代碼
"""from abc import ABC, abstractmethodclass DiscountStrategy(ABC):"""抽象策略類"""@abstractmethoddef apply_discount(self, price):passclass PercentDiscount(DiscountStrategy):"""具體策略類:打折策略"""def __init__(self, discount_percent):self.discount_percent = discount_percentdef apply_discount(self, price):return price * (1 - self.discount_percent / 100)class FullReduction(DiscountStrategy):"""具體策略類:滿減策略"""def __init__(self, full_price, reduction_price):self.full_price = full_priceself.reduction_price = reduction_pricedef apply_discount(self, price):return price - (price // self.full_price) * self.reduction_priceclass Promotion:"""上下文類:商場促銷"""def __init__(self, discount_strategy):self.discount_strategy = discount_strategydef apply_discount(self, price):return self.discount_strategy.apply_discount(price)if __name__ == "__main__":"""打折后價格:80.0滿減后價格:100"""# 商品原價original_price = 100# 選擇打折策略,打8折promotion = Promotion(PercentDiscount(20))discounted_price = promotion.apply_discount(original_price)print(f"打折后價格:{discounted_price}")# 選擇滿減策略,滿200減50promotion = Promotion(FullReduction(200, 50))discounted_price = promotion.apply_discount(original_price)print(f"滿減后價格:{discounted_price}")
四、優缺點
優點
- 靈活性和可擴展性:策略模式將算法封裝成獨立的類,使得可以獨立地添加、修改或替換算法,而不影響到客戶端的代碼,從而提高了代碼的靈活性和可擴展性。
- 易于維護:由于算法被封裝在獨立的類中,使得每個算法都有自己的類,易于理解和維護。
- 避免條件語句的使用:策略模式避免了使用大量的條件語句來選擇不同的算法,使得代碼更加清晰和易于理解。
- 符合開閉原則:策略模式符合開閉原則,即對擴展開放,對修改關閉,可以通過添加新的策略類來擴展功能,而不需要修改現有的代碼。
缺點
- 增加了類的數量:每個具體策略都需要一個對應的策略類,可能會增加類的數量。
- 客戶端必須知道所有的策略類:客戶端必須知道所有的策略類,并且在使用時需要顯式地選擇合適的策略類,這可能會增加客戶端的復雜性。
- 如果算法極少發生改變,那么沒有任何理由引入新的類和接口。使用該模式只會讓程序過于復雜。
【Python筆記】設計模式-CSDN博客