Topiqlo ロゴ

ストラテジー

公開日: 2025/06/02

ストラテジーパターンとは?──振る舞いを差し替える柔軟な設計戦略

はじめに

アプリケーションで「条件によって処理のアルゴリズムを変えたい」「処理内容を切り替えたい」──そんな場面は多くあります。
そうした要件に対して、

if
switch
による条件分岐を増やし続けるのは、保守性と拡張性を著しく損なう原因になります。
そこで登場するのが「ストラテジーパターン(Strategy Pattern)」。アルゴリズム(戦略)を切り離して差し替えられるようにするための設計手法です。

基本情報・概要

ストラテジーパターンは、アルゴリズムや振る舞いをオブジェクトとして抽象化し、動的に差し替え可能にするデザインパターンです。

主な目的:

  • 振る舞いの選択肢を外部化して管理
  • 条件分岐の削減と責任分離
  • 拡張可能なアルゴリズムの切り替え

実行時に処理内容を変えられる点が大きな特徴です。

比較・分類・特徴の表形式まとめ(任意)

構成要素役割
Contextストラテジーを使う本体。インターフェースを通じて実行
Strategyアルゴリズムの共通インターフェース(抽象)
ConcreteStrategy実際のアルゴリズム(振る舞い)を実装したクラス

ストラテジーは“切り替え可能な振る舞い”を外部オブジェクトとして管理するパターンです。

深掘り解説

✅ JavaScriptによる基本的な例

// Strategy インターフェース
class PaymentStrategy {
  pay(amount) {
    throw new Error("must implement pay()");
  }
}

// Concrete Strategies
class CreditCardStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`クレジットカードで${amount}円を支払いました`);
  }
}

class PayPayStrategy extends PaymentStrategy {
  pay(amount) {
    console.log(`PayPayで${amount}円を支払いました`);
  }
}

// Context
class PaymentProcessor {
  constructor(strategy) {
    this.strategy = strategy;
  }

  execute(amount) {
    this.strategy.pay(amount);
  }
}

const processor = new PaymentProcessor(new CreditCardStrategy());
processor.execute(1000);  // => クレジットカードで1000円を支払いました
  • Strategy
    は共通のインターフェース
  • Context
    は具体的な戦略を知らずに
    .pay()
    を呼び出すだけ
  • アルゴリズムの拡張・差し替えが容易

応用・発展的な使い方

  • ソートアルゴリズムの切り替え(例:QuickSort, MergeSort)
  • UIの描画戦略(描画方法やライブラリの差し替え)
  • 料金計算ロジック(条件別・キャンペーン別)
  • AIモデルの戦略選択(ルールベース/MLベースなど)

ストラテジーは「状況に応じて柔軟に変化する処理」に最適です。

よくある誤解と注意点(任意)

  • 使わなくても
    if
    でできるが?
    :保守性・拡張性を考えると設計分離は有効
  • 実装が煩雑に見える:処理が複雑・選択肢が多い場合にこそ活きる
  • コンテキストが戦略を意識しすぎる設計:インターフェースで隠蔽するのが理想
  • 戦略が使い捨てになる設計:再利用可能な粒度で定義すること

ストラテジーは**構造の分離ではなく「振る舞いの選択肢化」**を目指すものです。

まとめ

ストラテジーパターンは、条件分岐による処理切り替えをオブジェクト構造として外部化する設計パターンです。
拡張可能・差し替え可能・テストしやすい構造を実現し、ビジネスロジックやアルゴリズムの管理をシンプルに保つことができます。
「切り替えたくなる処理」があるなら、まずストラテジーで外出しできないかを検討するのが、柔軟な設計への第一歩です。