Strategyとは?

Strategyパターンは、アルゴリズムをカプセル化し、それらをオブジェクトとして扱うことで、アルゴリズムを動的に選択できるデザインパターンです。このパターンを使用すると、特定のタスクの実行方法を簡単に変更したり、拡張したりできます。

なぜStrategyが重要なのか?

  • 柔軟性の向上: アルゴリズムを切り替えることができ、システムの柔軟性が向上します。
  • コードの再利用: 共通のインターフェースを持つことで、異なるアルゴリズムを簡単に再利用できます。
  • 拡張性: 新しいアルゴリズムを追加する際に、既存のコードに影響を与えずに拡張が可能です。

修正前のコード

以下のコードは、異なるタイプの支払いを処理する単純な例です。修正前のコードでは、新しい支払い方法を追加するたびにPaymentProcessorクラスを変更する必要があります。

class PaymentProcessor
  def process(payment_type, amount)
    if payment_type == 'credit_card'
      process_credit_card(amount)
    elsif payment_type == 'paypal'
      process_paypal(amount)
    else
      raise "Unsupported payment type"
    end
  end

  def process_credit_card(amount)
    puts "Processing credit card payment of #{amount}"
  end

  def process_paypal(amount)
    puts "Processing PayPal payment of #{amount}"
  end
end

processor = PaymentProcessor.new
processor.process('credit_card', 100)
processor.process('paypal', 200)

問題点

  1. オープン・クローズド違反: 新しい支払い方法を追加するたびにPaymentProcessorクラスを変更する必要がある。
  2. メンテナンス性の低下: 支払い方法が増えるたびに、条件分岐が複雑化する。
  3. 再利用性の欠如: 支払い処理のロジックがPaymentProcessorにハードコーディングされている。

修正後のコード

Strategyパターンを使って、支払い処理を改善した例です。

class PaymentProcessor
  def initialize(strategy)
    @strategy = strategy
  end

  def process(amount)
    @strategy.process(amount)
  end
end

class CreditCardPayment
  def process(amount)
    puts "Processing credit card payment of #{amount}"
  end
end

class PayPalPayment
  def process(amount)
    puts "Processing PayPal payment of #{amount}"
  end
end

# Strategyの選択と実行
credit_card_processor = PaymentProcessor.new(CreditCardPayment.new)
credit_card_processor.process(100)

paypal_processor = PaymentProcessor.new(PayPalPayment.new)
paypal_processor.process(200)

解決された問題

  • オープン・クローズド原則の遵守: 支払い方法を追加する際にPaymentProcessorを変更する必要がなくなりました。
  • メンテナンス性の向上: 条件分岐がなくなり、コードがシンプルになりました。
  • 再利用性の向上: 各支払い方法は独立したクラスとして定義されているため、他のコンテキストでも再利用可能です。

まとめ

Strategyパターンを用いることで、コードの柔軟性、拡張性、再利用性を大幅に向上させることができます。このパターンは、特に条件分岐が多くなりがちなシステムにおいて、構造を整理し、保守性を向上させるために非常に有効です。デザインパターンを理解し、適切に適用することで、よりエレガントで強固なソフトウェア設計を実 現できます。