Strategy

  • 複数のアルゴリズムを別途のクラスとして定義し、切り替えができるようにするパターン

    • 親クラスでクライアントにアクセスさせるための共通APIを定義する
    • 子クラスで具体的なアルゴリズムを実装する
  • 「継承」「ポリモーフィズム」「移譲」を利用したパターン

    • StrategyConcreteStrategyは継承(実装)関係
    • Strategyクラスで共通のAPIを定義し、クライアントはその共通APIを利用することで、具体的なクラスの切り替えが可能になる
    • ContextクラスはStrategyオブジェクトに処理を移譲する

メリット・デメリット

メリット
  • 実行時にオブジェクト内で使用されるアルゴリズムを交換できる
  • アルゴリズムの実装の詳細を利用側のコードから分離できる
  • アルゴリズムの追加が容易になる
デメリット
  • アルゴリズムの種類が少ない場合、過剰な設計となる可能性がある

用途

  • ある問題を解決するための方法が複数あり、プログラム実行時に動的に切り替えたい場合
    • Contextに渡すConcreteStrategyによってアルゴリズムが切り替わる
  • クラス内にアルゴリズムを切り替えるために多くの条件文がある場合
    • 条件分岐を共通なAPIを持った個別のConcreteStrategyクラスに切り出している

デザインパターンの種類

振る舞いに関するデザインパターン

例(Mermaid)

  • Strategy
    • インターフェースもしくは抽象クラス
    • それぞれのアルゴリズムに共通のAPIを定義
  • ConcreteStrategy
    • Strategyを継承(実装)する子クラス
    • Strategyで定義された共通APIを満たすように具体的なアルゴリズムを実装する
  • Context
    • Strategy型のオブジェクトを内部に保時する
    • 具体的な処理はStrategyオブジェクトに移譲する
classDiagram
	class Context {
		strategy: Strategy
		contextMethod()
	}
	class Strategy {
		<<interface>>
		strategyMethod()
	}
	class ConcreteStrategy1{
		strategyMethod()
	}
	class ConcreteStrategy2{
		strategyMethod()
	}
	Context o--> Strategy
	ConcreteStrategy1 ..> Strategy
	ConcreteStrategy2 ..> Strategy
例2 
  • 異なるアルゴリズムでソートを実行
classDiagram
	class SortContext {
		strategy: SortStrategy
		sort()
	}
	class SortStrategy {
		sort()
	}
	class BubbleSort {
		sort()
	}
	class InsertionSort {
		sort()
	}
	SortContext o--> SortStrategy
	BubbleSort ..> SortStrategy
	InsertionSort ..> SortStrategy