策略模式
文章目录
引用《大话设计模式》书中对于策略模式的解析,策略模式就是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是互相的实现不一样,他可以以相同的方式调用所有的算法。
策略模式的结构:
- 封装类:也叫上下文,对策略进行二次封装,目的是避免高层模块对策略进行直接调用
- 抽象策略:通常是一个抽象接口
- 具体策略:接口实现类
目录结构:
.
├── go.mod
├── login_test.go
├── main.go
├── mycontext
│ └── doLoginContext.go
└── strategy
├── impl
│ ├── qqLoginStrategy.go
│ └── wxLoginStrategy.go
└── loginStrategy.go
策略接口:
package strategy
// Login 登陆抽象策略
type Login interface {
Login(userInfo string) (bool,error)
}
登陆策略的具体实现:
qq登陆策略:
package impl
import "fmt"
// qq登陆
type QQLoginStrategy struct {
}
// Login qq登陆
func (s *QQLoginStrategy) Login(userInfo string) (bool,error) {
fmt.Print("qq登陆")
return true,nil
}
微信登陆策略:
package impl
import "fmt"
// WxLoginStrategy wx登陆策略实现类
type WxLoginStrategy struct {
}
// Login 微信登陆策略
func (s WxLoginStrategy) Login(userInfo string) (bool,error) {
fmt.Print("wx登陆")
return true,nil
}
登陆策略上下文,进一步封装登陆策略,高层模块直接调用登陆上下文即可
package mycontext
import (
"awesomeProject3/strategy"
"awesomeProject3/strategy/impl"
"errors"
)
// LoginContext 登陆上下文
var LoginContext map[string]strategy.Login
// init 初始化登陆上下文
func init() {
LoginContext = map[string]strategy.Login{
"qq": &impl.QQLoginStrategy{},
"wx": &impl.WxLoginStrategy{},
}
}
// DoLogin 执行登陆策略
func DoLogin(loignType,userInfo string) (bool,error) {
if context,ok := LoginContext[loignType];ok{
return context.Login(userInfo)
}
return false,errors.New("非法登陆")
}
使用策略上下文完成登陆:
package main
import (
"awesomeProject3/mycontext"
"testing"
)
func TestLogin(t *testing.T) {
mycontext.DoLogin("wx","kevin")
}
策略模式让你能将各种算法的代码、 内部数据和依赖关系与其他代码隔离开来。 不同客户端可通过一个简单接口执行算法, 并能在运行时进行切换。