generated at
Strategyパターン



Strategy Interface
Concrete Strategy
Strategy Interfaceを実装する
Context
Strategyを切り替える
Client
利用者

具体的なアルゴリズムはConcrete Strategyの中にカプセル化し、Strategy Interfaceのみを表出させる
Contextが、どのStrategyを採用するかを切り替えることで目的のStrategyが使える
というパターン
例えば、Sortというinterfaceを提供しつつ、
具体的にどういうアルゴリズムでsortするかを切り替えるとか
入力を見てから、相性の良いアルゴリズムを選択するなど


mermaid
classDiagram Context --> Strategy : Uses Strategy <|-- ConcreteStrategyA Strategy <|-- ConcreteStrategyB Strategy <|-- ConcreteStrategyC class Context { +strategy: Strategy +execute(): void } class Strategy { +execute(): void } class ConcreteStrategyA { +execute(): void } class ConcreteStrategyB { +execute(): void } class ConcreteStrategyC { +execute(): void }

ts
const main = () => { // 引数に与えるStrategyを変更することで使える const context = new Context(new ConcreteStrategyA()); context.execute(); const context = new Context(new ConcreteStrategyB()); context.execute(); const context = new Context(new ConcreteStrategyC()); context.execute(); }; // Strategyを引数にとって、それを実行する class Context { strategy: Strategy; constructor(strategy: Strategy) { this.strategy = strategy; } execute() { this.strategy.execute(); } } // Strategy用のinterfaceを用意 interface Strategy { execute(): void; } // // 具体的な複数のStategyの実装 // ======================== class ConcreteStrategyA implements Strategy { execute() { console.log("Called ConcreteStrategyA.execute()"); } } class ConcreteStrategyB implements Strategy { execute() { console.log("Called ConcreteStrategyB.execute()"); } } class ConcreteStrategyC implements Strategy { execute() { console.log("Called ConcreteStrategyC.execute()"); } }


これはClassがあるがゆえに存在意義がある冗長なパターンmrsekut
classを使わなければ、もっと単純に表現できる


functionで書き換えた例
callback関数を渡して動作を切り替える
ts
type Strategy = () => void; const main = () => { mkContext(concreteStrategyA); mkContext(concreteStrategyB); mkContext(concreteStrategyC); }; const mkContext = (strategy: Strategy) => { strategy(); }; // // 具体的な複数のStategyの実装 // ======================== const concreteStrategyA: Strategy = () => { console.log("Called ConcreteStrategyA"); }; const concreteStrategyB: Strategy = () => { console.log("Called ConcreteStrategyB"); }; const concreteStrategyC: Strategy = () => { console.log("Called ConcreteStrategyC"); };

hs

例としてはわかりやすいが、実際のTypeScriptでこんな書き方はわざわざしないだろうmrsekut


Stateパターンと似ているらしい