0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するStrategyパターン:アルゴリズムを切り替え可能にする柔軟な設計

Posted at

概要

Strategy(ストラテジー)パターンは、
アルゴリズムや処理手順をオブジェクトとしてカプセル化し、実行時に自由に切り替えられるようにする設計パターンである。

条件分岐を排除しつつ、動作の切り替えや拡張を柔軟に行いたいときに有効
ソート手法、認証方法、価格計算、ログ戦略などに応用できる。


1. なぜStrategyが必要か?

❌ if/elseで処理パターンを切り替える設計はスケーラビリティに乏しい

if method == "credit":
    pay_credit()
elif method == "paypal":
    pay_paypal()

選択肢が増えるほど条件分岐が複雑化


✅ Strategyに切り出すことで構造的に拡張可能に

strategy = PayPalStrategy()
payment.set_strategy(strategy)
payment.process()

アルゴリズム切替がクラス設計に組み込まれる


2. 基本構造

✅ Strategyインターフェース

class PaymentStrategy:
    def pay(self, amount):
        raise NotImplementedError

✅ Concrete Strategy(実装)

class CreditCardStrategy(PaymentStrategy):
    def pay(self, amount):
        print(f"クレジットカードで {amount} 円支払い")

class PayPalStrategy(PaymentStrategy):
    def pay(self, amount):
        print(f"PayPalで {amount} 円支払い")

✅ Context(戦略を使う側)

class PaymentProcessor:
    def __init__(self, strategy: PaymentStrategy):
        self._strategy = strategy

    def set_strategy(self, strategy: PaymentStrategy):
        self._strategy = strategy

    def process(self, amount):
        self._strategy.pay(amount)

✅ 使用例

processor = PaymentProcessor(CreditCardStrategy())
processor.process(5000)

processor.set_strategy(PayPalStrategy())
processor.process(5000)

出力:

クレジットカードで 5000 円支払い  
PayPalで 5000 円支払い

3. Python的応用:関数ベースのストラテジー設計

def credit_pay(amount):
    print(f"[関数] クレジットで {amount}")

def paypal_pay(amount):
    print(f"[関数] PayPalで {amount}")

class PaymentProcessor:
    def __init__(self, strategy):
        self.strategy = strategy

    def process(self, amount):
        self.strategy(amount)
processor = PaymentProcessor(credit_pay)
processor.process(3000)

processor.strategy = paypal_pay
processor.process(3000)

関数もStrategyとして機能できるのがPythonの強み


4. 実務ユースケース

✅ 支払い、ログ出力、認証などの方式切替

特定処理を柔軟に差し替え可能にする構造


✅ データの変換・圧縮アルゴリズムの差し替え

→ 同じインターフェースで異なる処理戦略を適用


✅ システム構成に応じた動的な挙動制御

→ ローカル/クラウド、テスト/本番で戦略を差し替え


✅ 機械学習における予測モデルの統一インターフェース

→ モデルA, B, Cを同一戦略構造で扱い、切替可能に設計


5. よくある誤用と対策

❌ Contextクラスに戦略が固定実装されている

→ ✅ 戦略はContextの外部から注入できる構造にする


❌ Strategyの責務があいまいで肥大化する

→ ✅ 1戦略 = 1アルゴリズム に限定してSRPを守る


❌ Strategyの切り替えが実行中に許されない設計

→ ✅ set_strategy()など明示的切替用メソッドを提供


結語

Strategyパターンとは、“やり方の違いを構造で受け入れ、選択可能にする設計”である。

  • アルゴリズムをオブジェクト化し、選択・拡張・切替を柔軟に可能に
  • 条件分岐を排除して、開放/閉鎖原則に従ったスケーラブルなコードを実現
  • Pythonでは関数・クラスの両スタイルで実装でき、場面に応じた選択が可能

Pythonicとは、“処理の違いを柔らかく切り出し、選べるようにすること”。
Strategyパターンはその柔軟さを、選択可能な知性として設計に宿す技法である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?