策略模式(Strategy Pattern: Define a family of algorithms,encapsulate each one,andmake them interchangeable.)
中文解释为:定义一组算法,然后将这些算法封装起来,以便它们之间可以互换,属于一种对象行为型模式。总的来说策略模式是一种比较简单的模式,听起来可能有点费劲,其实就是定义一组通用算法的上层接口,各个算法实现类实现该算法接口,封装模块使用类似于Context的概念,Context暴漏一组接口,Context内部接口委托到抽象算 法层。
包含的角色罗列如下:
- 上下文角色(Context) :该角色一般是一个实现类或者封装类,起到一定的封装及隔离作用,实际接受请求并将请求委托给实际的算法实现类处理,避免外界对底层策略的直接访问;
- 抽象策略角色( Strategy) :该角色一般是一一个抽象角色,为接口或者抽象类扮演,定义具体策略角色的公共接口;
- 具体策略角色( ConcreteStrategy) :实现抽象策略角色的接口,为策略的具体实现类。
策略模式的优点如下:
-
所有策略放入一组抽象策略接口中,方便统一管理与实现; 策略模式的缺点如下:
-
策略模式每种策略都是单独类,策略很多时策略实现类也很可观;
-
客户端初始化Context的时候需要指定策略类,这样就要求客户端要熟悉各个策略,对调用方要求较高。
策略模式的应用场景如下:
- 需要自由切换算法的场景
- 需要屏蔽算法实现细节的场景
类图:
import "fmt"
type FlyBehavior interface {
Fly()
}
type QuackBehavior interface {
Quack()
}
type Duck struct {
fly FlyBehavior
quack QuackBehavior
}
func (d *Duck)Swim() {
fmt.Println("鸭子游泳")
}
func (d *Duck) Display (behavior FlyBehavior,quackBehavior QuackBehavior) {
behavior.Fly()
quackBehavior.Quack()
}
type FlyWithWings struct {}
func (f *FlyWithWings) Fly () {
fmt.Println("鸭子用翅膀飞")
}
type FlyNoWay struct {}
func (f *FlyNoWay) Fly () {
fmt.Println("鸭子飞不起来")
}
type Quack struct {}
func (f *Quack) Quack () {
fmt.Println("鸭子嘎嘎叫")
}
type Squeak struct {}
func (f *Squeak) Quack () {
fmt.Println("鸭子咔咔叫")
}
type Mute struct {}
func (f *Mute) Quack () {
fmt.Println("鸭子不能叫")
}
type ReadHead struct {
*Duck
fly *FlyWithWings
quack *Quack
}
func (r *ReadHead) Display () {
r.Swim()
r.Duck.Display(r.fly, r.quack)
}
type Wooden struct {
*Duck
fly *FlyNoWay
quack *Mute
}
func (r *Wooden) Display () {
r.Swim()
r.Duck.Display(r.fly,r.quack)
}
type Mallard struct {
*Duck
fly *FlyWithWings
quack *Quack
}
func (m *Mallard) Display () {
m.Swim()
m.Duck.Display(m.fly, m.quack)
}
type Rubber struct {
*Duck
fly *FlyNoWay
quack *Squeak
}
func (r *Rubber) Display () {
r.Swim()
r.Duck.Display(r.fly, r.quack)
}
flynoway := &FlyNoWay{}
flayWihtwings := &FlyWithWings{}
quack := &Quack{}
sqeak := &Squeak{}
mute := &Mute{}
duck := ReadHead{
Duck: &Duck{},
fly: flayWihtwings,
quack: quack,
}
duck.Display()
mallard := Mallard {
Duck: &Duck{},
fly: flayWihtwings,
quack: quack,
}
mallard.Display()
rub := Rubber {
Duck: &Duck{},
fly: flynoway,
quack: sqeak,
}
rub.Display()
wooden := Wooden{
Duck: &Duck{},
fly: flynoway,
quack: mute,
}
wooden.Display()
鸭子游泳
鸭子用翅膀飞
鸭子嘎嘎叫
鸭子游泳
鸭子用翅膀飞
鸭子嘎嘎叫
鸭子游泳
鸭子飞不起来
鸭子咔咔叫
鸭子游泳
鸭子飞不起来
鸭子不能叫