【从0开始学设计模式-13| 策略模式】

📅 2026/6/26 4:28:21
【从0开始学设计模式-13| 策略模式】
1.概念很多情况下实现某个目标的途径不止一条。比如我们要到一个地方去可以选择交通方式如地 铁、公交、骑行、步行等等有很多种软件开发中我们也常常会遇到类似的情况实现某一个功能如排序、查找等有多种算法可如果用通过硬编码将多种算法集中在一个类中。后续如果新增一种算法必将修改算法类也需要修改客户端代码来调用新的算法。在统一的算法类中封装 了大量的算法代码非常复杂不易维护和扩展。此时我们可以使用一种设计模式来实现灵活地选择算法还能方便的增加新的算法策略模式Strategy Pattern应运而生。定义在计算机编程中策略模式是一种行为软件设计模式可以在运行时选择算法2.策略模式的结构包含如下几个角色Context环境类环境类是使用算法的角色它在解决某个问题即实现某个方法时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例用于定义所采用的策略。Strategy抽象策略类它为所支持的算法声明了抽象方法是所有策略类的父类它可以是抽 象类或具体类也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实 现的算法。Concrete Strategy具体策略类它实现了在抽象策略类中声明的算法在运行时具体策略 类将覆盖在环境类中定义的抽象策略类对象使用一种具体的算法实现某个业务处理。策略模式是一个比较容易理解和使用的设计模式策略模式是对算法的封装它把算法的责任和算法本身分割开委派给不同的对象管理。3.策略模式的实现的例子3.1类图设计3.2代码实现业务相关的类publicenumResultType{/***/NORMAL,WEAK_ENEMY,STRONG_ENEMY,CLEAR,MISTAKE,DEAD;}抽象策略类定义了所有支持的算法行为的公共接口。在这里就是execute()方法并规定统一返回ResultType探索结果publicinterfaceIBehavior{ResultTypeexecute();}具体策略类它们实现了IBehavior接口各自封装了具体的逻辑和随机概率。例如NormalBehavior正常搜索模式遇到弱敌会返回WEAK_ENEMYAggressiveBehavior攻击模式遇到失误会返回MISTAKE等。//攻击模式publicclassAggressiveBehaviorimplementsIBehavior{OverridepublicResultTypeexecute(){if(newRandom().nextBoolean()){System.out.println(攻击模式轻松解决敌人);returnResultType.CLEAR;}System.out.println(攻击模式判断失误对方很强快防御);returnResultType.MISTAKE;}}//防御模式publicclassDefensiveBehaviorimplementsIBehavior{OverridepublicResultTypeexecute(){if(newRandom().nextBoolean()){System.out.println(防御模式暂时防守住了赶紧跑吧);returnResultType.CLEAR;}System.out.println(防御模式难道就这样结束了吗我不甘心啊);returnResultType.DEAD;}}//正常模式publicclassNormalBehaviorimplementsIBehavior{OverridepublicResultTypeexecute(){//随机产生探索结果RandomrandomnewRandom();intcountrandom.nextInt(100);if(count30){System.out.println(搜索模式一切正常);returnResultType.NORMAL;}elseif(count60){System.out.println(搜索模式前方有人送装备);returnResultType.WEAK_ENEMY;}System.out.println(搜索模式前方有强敌建议逃跑);returnResultType.STRONG_ENEMY;}}环境类内部维护了一个IBehavior类型的引用并且提供了explore()方法。使用了Setter这意味着可以在游戏运行的途中随时替换冒险者的行为策略。publicclassAdventure{//维持了一个对抽象策略类的引用实例SetterprivateIBehaviorbehavior;publicAdventure(IBehaviorbehavior){this.behaviorbehavior;}publicResultTypeexplore(){returnthis.behavior.execute();}}客户端publicclassClient{publicstaticvoidmain(String[]args){//从普通模式开始AdventureadventurenewAdventure(newNormalBehavior());mainLoop:do{//执行explore()这里是策略模式的关键不需要关心“当前是什么模式该怎么做”它只需要无脑调用behavior.execute()即可//根据执行的结果去动态更新对象类型选择下一步的操作switch(adventure.explore()){caseDEAD:System.out.println(SystemGame Over);breakmainLoop;caseCLEAR:caseSTRONG_ENEMY:adventure.setBehavior(newNormalBehavior());break;caseMISTAKE:adventure.setBehavior(newDefensiveBehavior());break;caseWEAK_ENEMY:adventure.setBehavior(newAggressiveBehavior());break;caseNORMAL:default:break;}}while(true);}}演示4 策略模式适用环境策略模式用于算法的自由切换和扩展它是应用较为广泛的设计模式之一。策略模式对应于解决某一问题的一个算法族允许用户从该算法族中任选一个算法来解决某一问题同时可以方便地更换算法或者增加新的算法。只要涉及到算法的封装、复用和切换都可以考虑使用策略模式。4.1 主要优点你可以在运行时切换对象内的算法。你可以将算法的实现和使用算法的代码隔离开来。你可以使用组合来代替继承。你无需对上下文进行修改就能够引入新的策略符合开闭原则。提供了一种算法的复用机制由于将算法单独提取出来封装在策略类中因此不同的环境类可以方 便地复用这些策略类。可以避免多重条件选择语句。4.2 主要缺点客户端必须知道所有的策略类并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算 法的区别以便适时选择恰当的算法。策略模式将造成系统产生很多具体策略类任何细小的变化都将导致系统要增加一个新的具体策略类。无法同时在客户端使用多个策略类也就是说在使用策略模式时客户端每次只能使用一个策略 类不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。4.3 适用场景一个系统需要动态地在几种算法中选择一种那么可以将这些算法封装到一个个的具体算法类中 然后通过里氏替换原则进行动态切换。一个对象有很多的行为如果不用恰当的模式这些行为就只好使用多重条件选择语句来实现。不希望客户端知道复杂的、与算法相关的数据结构在具体策略类中封装算法与相关的数据结构 可以提高算法的保密性与安全性。一句话总结策略模式是一种行为设计模式它将一系列不同的解决办法算法分别封装成独立的类程序在运行时能够根据情况动态、自由地切换方法方法之间可以相互替换更换解决办法时无需修改原有的主流程代码。如果这篇文章对你有帮助欢迎点赞、评论、关注、收藏。你们的支持是我前进的动力