Strategy
-
複数のアルゴリズムを別途のクラスとして定義し、切り替えができるようにするパターン
- 親クラスでクライアントにアクセスさせるための共通APIを定義する
- 子クラスで具体的なアルゴリズムを実装する
-
「継承」「ポリモーフィズム」「移譲」を利用したパターン
StrategyとConcreteStrategyは継承(実装)関係Strategyクラスで共通のAPIを定義し、クライアントはその共通APIを利用することで、具体的なクラスの切り替えが可能になるContextクラスはStrategyオブジェクトに処理を移譲する
メリット・デメリット
メリット
- 実行時にオブジェクト内で使用されるアルゴリズムを交換できる
- アルゴリズムの実装の詳細を利用側のコードから分離できる
- アルゴリズムの追加が容易になる
デメリット
- アルゴリズムの種類が少ない場合、過剰な設計となる可能性がある
用途
- ある問題を解決するための方法が複数あり、プログラム実行時に動的に切り替えたい場合
Contextに渡すConcreteStrategyによってアルゴリズムが切り替わる
- クラス内にアルゴリズムを切り替えるために多くの条件文がある場合
- 条件分岐を共通なAPIを持った個別の
ConcreteStrategyクラスに切り出している
- 条件分岐を共通なAPIを持った個別の
デザインパターンの種類
振る舞いに関するデザインパターン
例(Mermaid)
Strategy- インターフェースもしくは抽象クラス
- それぞれのアルゴリズムに共通のAPIを定義
ConcreteStrategyStrategyを継承(実装)する子クラスStrategyで定義された共通APIを満たすように具体的なアルゴリズムを実装する
ContextStrategy型のオブジェクトを内部に保時する- 具体的な処理は
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