Strategyパターン
Strategy Interface
Concrete Strategy
Strategy Interfaceを実装する
Context
Strategyを切り替える
Client
利用者
具体的なアルゴリズムはConcrete Strategyの中にカプセル化し、Strategy Interfaceのみを表出させる
Contextが、どのStrategyを採用するかを切り替えることで目的のStrategyが使える
というパターン
例えば、Sortというinterfaceを提供しつつ、
具体的にどういうアルゴリズムでsortするかを切り替えるとか
入力を見てから、相性の良いアルゴリズムを選択するなど
例
code: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
}
code: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.icon
classを使わなければ、もっと単純に表現できる
functionで書き換えた例
callback関数を渡して動作を切り替える
code: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.icon