策略模式

最后更新于:2022-04-02 02:35:44

[TOC] ## 策略模式 优点: 1. 提供了对"开闭原则"的完美支持 2. 避免使用多条件的转移语句 3. 提供了管理相关算法族的办法 缺点: 1. 客户端必须知道所有的策略类 2. 策略模式将造成产生很多策略类 适合场景: 1. 需要动态地在几种算法中选择一种 2. 多个类区别仅在于它们的行为或算法不同的场景 ### 简单demo
main.go ``` package main import "log" // 实现一个上下文的类 type Context struct { Strategy } // 抽象的策略 type Strategy interface { Do() } type Strategy1 struct { } func (s *Strategy1) Do() { log.Printf("%v","实现策略1") } type Strategy2 struct { } func (s *Strategy2) Do() { log.Printf("%v","实现策略2") } func main() { context := Context{} context.Strategy=&Strategy1{} context.Do() strategy2 :=&Strategy2{} context.Strategy=strategy2 context.Do() /** 2020/05/12 07:29:56 实现策略1 2020/05/12 07:29:56 实现策略2 */ } ```

### 实战模拟 实现一个日志记录器满足:文件记录和数据库记录2种方式
详情 ``` package main import "log" type LogManager struct { Logging } func NewLogManager(logging Logging) *LogManager { return &LogManager{Logging: logging} } type Logging interface { Info() Error() } type FileLogging struct{ } func (f *FileLogging) Info() { log.Printf("%v","文件记录 info") } func (f *FileLogging) Error() { log.Printf("%v","文件记录 Error") } type DbLogging struct{ } func (f *DbLogging) Info() { log.Printf("%v","数据库记录 info") } func (f *DbLogging) Error() { log.Printf("%v","数据库记录 Error") } func main() { filelog := &FileLogging{} manager := NewLogManager(filelog) manager.Info() manager.Error() dblog:=&DbLogging{} manager.Logging=dblog manager.Info() manager.Error() } ```

### 遍历策略模式
main.go ``` package main import "log" type LogManager struct { Log []Logging } func NewLogManager(logging ...Logging) *LogManager { return &LogManager{ Log: logging, } } func (l *LogManager) Info() { for _, logging := range l.Log { logging.Info() } } func (l *LogManager) Error() { for _, logging := range l.Log { logging.Error() } } type Logging interface { Info() Error() } type FileLogging struct{ } func (f *FileLogging) Info() { log.Printf("%v","文件记录 info") } func (f *FileLogging) Error() { log.Printf("%v","文件记录 Error") } type DbLogging struct{ } func (f *DbLogging) Info() { log.Printf("%v","数据库记录 info") } func (f *DbLogging) Error() { log.Printf("%v","数据库记录 Error") } func main() { filelog := &FileLogging{} dblog:=&DbLogging{} manager := NewLogManager(filelog,dblog) manager.Info() manager.Error() } ```

';