简介
策略模式(Strategy Pattern)属于行为型设计模式。将每一个算法封装到具有共同接口的独立类中,根据需要来绑定策略,使得具体实现和策略解耦。
当你想使用对象中各种不同的算法变体,使用if...else 所带来的复杂和难以维护,可使用策略模式。或者当有许多相同类,它们仅在执行某些行为时略有不同,可使用策略模式。
作用
- 策略算法可以自由切换,保持策略与执行类的松耦合。
- 避免使用多重条件判断,不同环境角色可以组装多个策略。
- 扩展性良好,可以随时增删策略行为。
- 体现了多用组合,少用继承。
实现步骤
- 建立一个策略接口。
- 新建多个策略行为类,实现该策略接口。
- 建立一个抽象环境角色类,并将策略接口组合进来。是否需要抽象类可选。
- 建立多个环境角色类来继承该抽象类。
- 可以动态改变环境角色的策略行为。
不同语言设计模式源码下载:
https://github.com/microwind/design-pattern
UML

Java代码
状态基础接口
| |
| public interface Strategy { |
| public void run(); |
| } |
策略实现类
| |
| public class StrategyA implements Strategy { |
| |
| @Override |
| public void run() { |
| System.out.println("StrategyA::run()."); |
| } |
| } |
| |
| public class StrategyB implements Strategy { |
| |
| @Override |
| public void run() { |
| System.out.println("StrategyB::run()."); |
| } |
| } |
| |
| public class StrategyC implements Strategy { |
| |
| @Override |
| public void run() { |
| System.out.println("StrategyC::run()."); |
| } |
| } |
抽象业务类
| |
| public abstract class Context { |
| |
| protected Strategy strategy; |
| |
| public void setStrategy(Strategy strategy) { |
| this.strategy = strategy; |
| } |
| |
| public void action() { |
| this.strategy.run(); |
| } |
| |
| } |
具体业务类
| |
| public class ContextCat extends Context { |
| |
| public ContextCat() { |
| |
| System.out.println("ContextCat::setStrategy(StrategyC)."); |
| this.setStrategy(new StrategyC()); |
| } |
| } |
| |
| public class ContextDog extends Context { |
| public ContextDog() { |
| |
| System.out.println("ContextDog::setStrategy(StrategyB)."); |
| this.setStrategy(new StrategyB()); |
| } |
| } |
测试调用
| |
| |
| |
| |
| |
| |
| Context contextCat = new ContextCat(); |
| contextCat.action(); |
| |
| |
| System.out.println("reset contextCat'strategy to StrategyA."); |
| contextCat.setStrategy(new StrategyA()); |
| contextCat.action(); |
| |
| |
| Context contextGog = new ContextDog(); |
| contextGog.action(); |
Go代码
状态基础接口
| |
| |
| type Strategy interface { |
| Run() |
| } |
| |
| |
| func Init() { |
| fmt.Println("strategy init!") |
| } |
策略实现类
| |
| type StrategyA struct { |
| } |
| |
| |
| func (s *StrategyA) Run() { |
| fmt.Println("StrategyA::Run") |
| } |
| |
| type StrategyB struct { |
| } |
| |
| |
| func (s *StrategyB) Run() { |
| fmt.Println("StrategyB::Run") |
| } |
| |
| |
| type StrategyC struct { |
| } |
| |
| |
| func (s *StrategyC) Run() { |
| fmt.Println("StrategyC::Run") |
| } |
抽象业务类
| |
| type Context struct { |
| strategy Strategy |
| } |
| |
| |
| func (c *Context) SetStrategy(s Strategy) { |
| c.strategy = s |
| } |
| |
| |
| func (c *Context) Run() { |
| c.strategy.Run() |
| } |
具体业务类
| |
| |
| type ContextCat struct { |
| context Context |
| } |
| |
| |
| func (c *ContextCat) Init() { |
| c.context.SetStrategy(&StrategyC{}) |
| fmt.Println("ContextCat::init. setStrategy(StrategyC)") |
| } |
| |
| |
| func (c *ContextCat) Run() { |
| fmt.Println("ContextCat::run") |
| c.context.Run() |
| } |
| |
| |
| type ContextDog struct { |
| context Context |
| } |
| |
| |
| func (c *ContextDog) Init() { |
| c.context.SetStrategy(&StrategyB{}) |
| fmt.Println("ContextDog::init. setStrategy(StrategyB)") |
| } |
| |
| |
| func (c *ContextDog) Run() { |
| fmt.Println("ContextDog::run") |
| c.context.Run() |
| } |
测试调用
| func main() { |
| fmt.Println("test start:") |
| |
| src.Init() |
| |
| |
| |
| |
| |
| |
| |
| context := src.Context{} |
| |
| |
| context.SetStrategy(&src.StrategyA{}) |
| |
| |
| context.Run() |
| |
| |
| context.SetStrategy(&src.StrategyB{}) |
| |
| context.Run() |
| |
| |
| context.SetStrategy(&src.StrategyC{}) |
| context.Run() |
| |
| |
| |
| |
| contextCat := src.ContextCat{} |
| contextCat.Init() |
| contextCat.Run() |
| |
| |
| contextDog := src.ContextDog{} |
| contextDog.Init() |
| contextDog.Run() |
| } |
更多语言版本
不同语言设计模式源码:https://github.com/microwind/design-pattern
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战