策略模式(Strategy Pattern)是一種行為型設計模式,它定義了一系列算法,并將每個算法封裝起來,使它們可以互相替換。策略模式讓算法的變化不會影響使用算法的客戶端,使得算法可以獨立于客戶端的變化而變化。
策略模式的結構
策略模式主要包含以下角色:
- 策略接口(Strategy):定義算法的接口。
- 具體策略類(Concrete Strategy):實現策略接口的具體算法。
- 上下文類(Context):使用策略對象的上下文,維護對策略對象的引用,并在需要時調用策略對象的方法。
示例
假設我們要設計一個計算不同類型折扣的系統。我們可以使用策略模式來實現這一功能。
定義策略接口
from abc import ABC, abstractmethodclass DiscountStrategy(ABC):@abstractmethoddef apply_discount(self, price: float) -> float:pass
實現具體策略類
class NoDiscount(DiscountStrategy):def apply_discount(self, price: float) -> float:return priceclass PercentageDiscount(DiscountStrategy):def __init__(self, percentage: float):self.percentage = percentagedef apply_discount(self, price: float) -> float:return price * (1 - self.percentage / 100)class FixedAmountDiscount(DiscountStrategy):def __init__(self, amount: float):self.amount = amountdef apply_discount(self, price: float) -> float:return max(0, price - self.amount)
定義上下文類
class PriceCalculator:def __init__(self, strategy: DiscountStrategy):self.strategy = strategydef calculate_price(self, price: float) -> float:return self.strategy.apply_discount(price)
使用策略模式
def main():original_price = 100.0no_discount = NoDiscount()ten_percent_discount = PercentageDiscount(10)five_dollar_discount = FixedAmountDiscount(5)calculator = PriceCalculator(no_discount)print(f"Original price: ${original_price}, No discount: ${calculator.calculate_price(original_price)}")calculator.strategy = ten_percent_discountprint(f"Original price: ${original_price}, 10% discount: ${calculator.calculate_price(original_price)}")calculator.strategy = five_dollar_discountprint(f"Original price: ${original_price}, $5 discount: ${calculator.calculate_price(original_price)}")if __name__ == "__main__":main()
策略模式的優缺點
優點
- 開閉原則:可以在不修改上下文類的情況下引入新的策略,實現算法的獨立變化。
- 消除條件語句:通過使用策略模式,可以避免在上下文類中使用大量的條件語句。
- 提高代碼復用性:不同的策略類可以復用相同的算法接口,提高代碼的復用性和可維護性。
缺點
- 增加類的數量:每個策略都是一個單獨的類,可能會增加類的數量,導致代碼復雜度增加。
- 策略切換的開銷:在運行時切換策略可能會帶來一些性能開銷。
策略模式的適用場景
- 算法需要在運行時選擇:當一個系統需要在運行時從多個算法中選擇一個時,可以使用策略模式。
- 避免條件語句:當一個類中包含大量與算法選擇相關的條件語句時,可以使用策略模式消除這些條件語句。
- 需要重用算法:當多個類需要復用相同的算法時,可以將這些算法提取到獨立的策略類中,通過策略模式進行重用。
總結
策略模式是一種行為型設計模式,通過定義一系列算法并將每個算法封裝起來,使它們可以互相替換,從而實現算法的獨立變化和復用。策略模式可以提高代碼的靈活性和可維護性,適用于算法需要在運行時選擇或消除條件語句的場景。合理使用策略模式,可以顯著提高代碼的質量和設計水平。