Site icon imageTomoMemo.dev

Memo on programming. Provided by Tomo with passion.

Pythonで学ぶデザインパターン[Strategy]

Icon in a callout block
Python 100Days Challenge Day25

Strategyパターンについて学んでいく。

概要

  • 処理そのものをクラスとして定義し、その処理を実行するオブジェクトの外部から差し替えられるようにするデザインパターン
  • 動作を簡単に変更したり、追加したりできる

仮に、あなたはオンラインショップを運営しているとして、このショップでは商品の送料計算方法を状況に応じて変えたいとする。

通常配送、速達配送、割引適用配送など、複数の配送方法手段を持っている。

Strategyパターンを使うと、これらの異なる送料計算方法を柔軟に切り替えられる。

Strategyパターンのコードを書いてみる

  • コードの流れ
    • ShippingCostStrategyという抽象クラスを作成
      • calculateという抽象メソッドを定義
    • strategyクラスを作成して異なる送料を計算する
      • RegularShipping
      • ExpressShipping
      • DiscountShipping
    • Orderクラスを作成する
      • Strategyオブジェクトを保持して必要に応じて切り替える
    • Orderオブジェクトを使って異なる処理を柔軟に切り替える

from abc import ABC, abstractmethod

# strategyのベースクラス
class ShippingCostStrategy(ABC):
    @abstractmethod
    def calculate(self, order):
        pass

# 送料毎のStrategyクラス
class RegularShipping(ShippingCostStrategy):
    def calculate(self, order):
        return 5.0
        
class ExpressShipping(shippingCostStrategy):
    def calculate(self, order):
        return 10.0
        
class DiscountShipping(shippingCostStrategy):
    def calculate(self, order):
        return 3.0
        
# オーダーclass
class Order:
    def __init__(self, cost_strategy: ShippingCostStrategy):
        self.cost_strategy = cost_strategy
        
    def set_shipping_strategy(self, cost_strategy: ShippingCostStrategy):
        self.cost_strategy = cost_strategy
        
    def calculate_shipping_cost(self):
        return self.cost_strategy.calculate(self)


# 送料計算を柔軟に切り替えて使用する
order = Order(RegularShipping())
print(f"通常配送:")

order.set_shipping_strategy(ExpressShipping())
print(f"速達配送:", order.calculate_shipping_cost())

order.set_shipping_strategy(DiscountShipping())
print(f"割引適用配送:", order.calculate_shipping_cost())

> 
通常配送: 5.0
速達配送: 10.0
速達配送: 3.0

中々いい感じ。

Powered by Tomo with passion.