ストラテジーパターンは、アルゴリズムをクラスとして定義し、それぞれのアルゴリズムを独立させることで、クライアントが必要に応じてアルゴリズムを選択できるようにするデザインパターンです。このパターンを使用すると、アルゴリズムの変更が容易になり、コードの再利用性が高まります。
ストラテジーパターンは以下の3つの要素で構成されています。
以下の例では、異なる割引戦略を持つオンラインストアのシナリオを考えます。割引戦略として「通常割引」と「セール割引」を実装します。
from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
@abstractmethod
def apply_discount(self, price: float) -> float:
pass
このコードでは、DiscountStrategy
という抽象クラスを定義し、apply_discount
メソッドを抽象メソッドとして宣言しています。このメソッドは、価格に対する割引を適用するために実装される必要があります。
次に、具体的な割引戦略を2つ実装します。
class NoDiscount(DiscountStrategy):
def apply_discount(self, price: float) -> float:
return price
class SaleDiscount(DiscountStrategy):
def apply_discount(self, price: float) -> float:
return price * 0.8 # 20%の割引
NoDiscount
クラスは、割引を適用しない戦略を実装します。SaleDiscount
クラスは、20%の割引を適用する戦略を実装します。次に、ストラテジーを使用するクラスを定義します。
class ShoppingCart:
def __init__(self):
self.items = []
self.discount_strategy = NoDiscount() # デフォルトの割引戦略
def add_item(self, price: float):
self.items.append(price)
def set_discount_strategy(self, strategy: DiscountStrategy):
self.discount_strategy = strategy
def calculate_total(self) -> float:
total = sum(self.items)
return self.discount_strategy.apply_discount(total)
ShoppingCart
クラスは、アイテムを追加し、合計金額を計算するためのメソッドを持っています。また、割引戦略を設定するためのメソッドも提供しています。
最後に、これらのクラスを使用してストラテジーパターンを実際に動かしてみましょう。
if __name__ == "__main__":
cart = ShoppingCart()
cart.add_item(100)
cart.add_item(200)
print("合計金額(割引なし):", cart.calculate_total())
cart.set_discount_strategy(SaleDiscount())
print("合計金額(20%割引):", cart.calculate_total())
このコードを実行すると、割引なしの合計金額と20%割引を適用した合計金額が表示されます。
ストラテジーパターンは、アルゴリズムをクラスとして定義し、必要に応じて変更できる柔軟性を提供します。このパターンを使用することで、コードの再利用性が高まり、保守性も向上します。異なるアルゴリズムを簡単に追加・変更できるため、システムの拡張が容易になります。