🦔

【デザインパターン】ストラテジーパターン - Strategy

2021/06/20に公開

ストラテジーパターンとは、GoF(Gang of Four)デザインパターンの一つであり、戦略部分(アルゴリズム)をクラス単位で定義することで、切り替えや拡張を容易にする方法です。

Strategyという英単語は、戦略を意味します。

ストラテジーパターンのコード

a, b, c, d, eの5つのアルファベットを並び替えしたり、加工するコードです。Strategyクラスのインスタンスを一度生成した後は、setStrategyメソッドによって戦略を切り替えて処理を実行します。

interface IStrategy {
    doAlgorithm(data: string[]): string[]
}

class Strategy {
    private strategy: IStrategy
    constructor(strategy: IStrategy) {
        this.strategy = strategy
    }

    public setStrategy(strategy: IStrategy) {
        this.strategy = strategy
    }
    public doSomeBusinessLogic() {
        return this.strategy.doAlgorithm(['b', 'a','e', 'd', 'c'])
    }
}
// 昇順ソート
class NormalSort implements IStrategy {
    public doAlgorithm = (data: string[]) => data.sort((a, b) => a < b ? -1 : 1)
}
// 降順ソート
class ReverseSort implements IStrategy {
    public doAlgorithm = (data: string[]) => data.sort((a, b) => a > b ? -1 : 1)
}
// 大文字に変換
class ToUpperCase implements IStrategy {
    public doAlgorithm = (data: string[]) => data.map((v) => v.toUpperCase())
}

const strategy = new Strategy(new NormalSort())
console.log(strategy.doSomeBusinessLogic()) // ["a", "b", "c", "d", "e"]

strategy.setStrategy(new ReverseSort())
console.log(strategy.doSomeBusinessLogic()) // ["e", "d", "c", "b", "a"]

strategy.setStrategy(new ToUpperCase())
console.log(strategy.doSomeBusinessLogic()) // ["B", "A", "E", "D", "C"]
  • NormalSort, ReverseSort, ToUpperCase 戦略部分の各クラス
  • doSomeBusinessLogic() 処理を実行するメソッド
  • setStrategy() 戦略の切り替えを容易に出来るようにするためのsetter

メリット

戦略部分の実装の詳細を、それを使用するコード(Strategyクラス)から分離できます。

条件を増やしたいときは、if文を追加するのではなく、新たにクラスを追加するだけで済みます。そのため、既存のコードにあまり影響を与えることなくコードを拡張できます。

これは拡張に対して開放的であり、変更に対して閉鎖的であるべきとするオープン・クローズドの原則を守ることになります。

参考

https://refactoring.guru/design-patterns/strategy

Discussion