Introduction
The strategy is a behavior pattern. It fits where multiple choices for an interface are available and the design would allow switching them dynamically.
Conditions
- A set of choices with similarity in the interface
- Dynamic update of a choice
Example
- A cache with evictions
- Multiple eviction algorithms
- Cache could switch to a different algorithm dynamically
- A duck type has a variety of flying behaviors. A duck can fly very fast, slow and no-fly.
Implementation
Define what a duck is.
// duck_type.go
package main
type duck struct {
flyBehavior
}
Define fly behavior
// fly_behavior.go
package main
type flyBehavior interface {
fly()
nofly()
}
Define the fast duck fly behavior
//fast_duck.go
package main
import "fmt"
type duckF18 struct {
}
func (d *duckF18) fly() {
fmt.Printf("%+v\n", "flying like a F18")
}
func (d *duckF18) nofly() {
fmt.Printf("%+v\n", "not implemented")
}
Define no fly behavior
// nofly_duck.go
package main
import "fmt"
type duckNofly struct {
}
func (d *duckNofly) fly() {
fmt.Printf("%+v\n", "not implemented")
}
func (d *duckNofly) nofly() {
fmt.Printf("%+v\n", "no flying")
}
// main.go
package main
func createNewDuck(f flyBehavior) *duck {
return &duck{
flyBehavior: f,
}
}
func (d *duck) setFlyBehavior(f flyBehavior) {
d.flyBehavior = f
}
func main() {
// f18 duck
aDuck := createNewDuck(&duckF18{})
aDuck.flyBehavior.fly()
// duck switches to no fly
aDuck.setFlyBehavior(&duckNofly{})
aDuck.flyBehavior.fly()
}