GoFデザインパターン ~Strategyパターン~
Strategyパターンとは
ある問題に対して複数の解法が存在する場合、コンテキストに合わせてアルゴリズムのスイッチングを簡単に行えるようにするためのパターン。Strategyは「戦略」という意味。
Strategyパターンにおける役割
name | description |
---|---|
Strategy | アルゴリズムを利用するためのインターフェース。 |
ConcreteStrategy | Strategyインターフェースを継承し、アルゴリズムの具体的な実装を行う。 |
Context | 文脈に沿ってStrategyを呼び出す役。Strategyは外部からContextに注入し、ContextとStrategyは疎結合になるようにする。 |
GoでStrategyパターンの簡単な枠組みを実装してみる
$ tree ./ ├── context.go ├── main.go └── strategy ├── strategy.go ├── strategy_alpha.go └── strategy_beta.go
Strategyパッケージ
package strategy type Strategy interface { Call() } type AlphaStrategy struct{} func (*AlphaStrategy) Call() { // Do something } type BetaStrategy struct{} func (*BetaStrategy) Call() { // Do something }
Strategy interface
がアルゴリズムを実行するための窓口になる。アルゴリズムを利用する側は Strategy interface
にのみ依存する。
AlphaStrategy
BetaStrategy
はそれぞれ Strategy interface
を継承していて、アルゴリズムの具体的な実装を行う。
Mainパッケージ
package main import ( "os" "github.com/saekis/go-design-pattern/8_strategy/strategy" ) func main() { var s strategy.Strategy switch os.Args[1] { case "alpha": s = &strategy.AlphaStrategy{} case "beta": s = &strategy.BetaStrategy{} default: return } Context{s}.Exec() } type Context struct { strategy strategy.Strategy } func (c *Context) Exec() { c.strategy.Call() }
Context.Exec()
はアルゴリズムを利用するが、実際のアルゴリズムの処理は注入されたStrategyに委譲する。こうすることで、アルゴリズムを利用する文脈とアルゴリズムの実装を疎結合にすることができるので、アルゴリズムのスイッチングが容易になり、テスタビリティの向上が期待できる。