当前位置: 首页 > 后端技术 > Java

设计模式[12]——最近大火的攻略模式

时间:2023-04-01 17:00:09 Java

,还是从那种画面开始的。之前我们其实已经解释了结构模式,剩下的都是行为模式。三种模式的区别:Creationalmode:如何创建一个对象Structuralmode:一个对象的内部结构是如何构建的Behavioralmode:当涉及到策略时,我们如何理解这个对象是如何工作的(它能做什么)图案?从北京到上海,可以坐飞机、高铁、绿皮车,甚至可以骑自行车。这些不同的方式就是策略。一件商品可以直接立减50%,也可以加100再立减40%,也可以在立减5.5折后返还代金券。这些也是策略。带200去超市买东西,可以买零食,也可以买日用品,也可以什么都不买。这些也是策略。在上面的例子中,我们其实可以发现不同的策略是可以互换的,甚至策略细节是可以混搭的。很多时候,为了方便策略的扩展和替换,我们可以使用策略模式。如果把所有的策略都写在一个类中是可以的,那么维护代码会越来越复杂,维护起来只会越来越困难。里面会充斥着各种if-else,如果算法越来越复杂,就会越来越复杂。并拉动全身,便只剩下水桶跑了。策略模式是指具有一定动作内容的相对稳定的策略名称。谋略模式在古代也被称为“谋略”,简称“谋略”,如《汉书·高帝纪上》:“汉王从其谋略”。这里的“计”指的是计谋和谋略。策略模型有比较稳定的形式,如“避实取虚”、“奇胜”等。一定的战略模型既可以应用于战略决策,也可以应用于战术决策;它可以在大型系统的全局和局部操作中实现。再举个所有打工仔都知道的例子,比如说每个人都要交个人所得税。我们知道,个人所得税的计算方法非常复杂。税法的计算是一种行为,可能有不同的实现算法,所以每一种计算算法都是不同的。是一种策略。这些策略随时可能被替换,所以我们定义了一系列便于替换和相互隔离的算法,并进行了封装。这称为策略模式。策略模式的作用策略模式一般有三个作用:抽象策略类(Strategy):将策略的行为抽象出公共接口具体策略类(ConcreteStrategy):使用Strategy接口实现一些具体的算法,并有可能很多具体的策略Context也可以相互替换:一般策略和使用策略的方法都是封装好的,屏蔽了上层调用的细节,直接调用即可。策略模式的demo创建一个抽象的策略接口:publicinterfaceStrategy{intdoStrategy();}创建2个具体的策略类分别执行策略:publicclassConcreteStrategy1implementsStrategy{@OverridepublicintdoStrategy(){System.out.println("执行策略1...");返回1;}}publicclassConcreteStrategy2implementsStrategy{@OverridepublicintdoStrategy(){System.out.println("执行策略2...");返回2;}}创建一个上下文类来封装策略类:publicclassContext{privateStrategystrategy;公共上下文(策略策略){this.strategy=strategy;}publicvoidexecuteStrategy(){strategy.doStrategy();}}测试类:publicclassTest{publicstaticvoidmain(String[]args){Contextcontext1=newContext(newConcreteStrategy1());context1.executeStrategy();context1=newContext(newConcreteStrategy2());context1.executeStrategy();}}测试结果:Executionstrategy1Executionstrategy2可以看到只要使用不同的策略,就可以执行不同的结果。红包策略实战比如工作中有分配相关的策略。场景是有红包分发给几个人,但是会有不同的分发策略。这里的不同的分配策略实际上是使用策略模式来实现的。可以随机分配,也可以平均分配,也可以按各种权重分配等。这里只演示两种分布:首先定义一个红包类,包括红包的数量(我们以分为单位存储整数,以避免小数点不准确)publicclassRedPackage{publicintremainSize;publicintremainMoney;publicRedPackage(intremainSize,intremainMoney){this.remainSize=remainSize;this.remainMoney=remainMoney;}}定义分配策略抽象类:importjava.util.List;publicinterfaceAllocateStrategy{Listallocate(RedPackageredPackage);}average分配的时候,如果不能平均,那么先增加或者减少:importjava.util.ArrayList;importjava.util.List;publicclassAverageAllocateStrategy实现AllocateStrategy{@OverridepublicListallocate(RedPackageredPackage){Listresults=newArrayList<>();整数和=redPackage.remainMoney;整数平均值=sum/redPackage.remainSize;对于(inti=0;iallocate(RedPackageredPackage){返回ranRedPackage(redPackage.remainSize,redPackage.remainMoney);}publicListranRedPackage(Integercount,Integermoney){Listresult=newArrayList<>();for(inti=0;iexecuteStrategy(RedPackageredPackage){returnstrategy.allocate(redPackage);}}测试类:importjava.util.List;公共类测试{publicstaticvoidmain(String[]args){RedPackageredPackage=newRedPackage(10,102);上下文context=newContext(newRandomAllocateStrategy());Listlist=context.executeStrategy(redPackage);list.forEach(l->System.out.print(l+""));System.out.println("");context=newContext(newAverageAllocateStrategy());列表=context.executeStrategy(redPackage);list.forEach(l->System.out.print(l+""));}}可以看出分配的数量确实会随着策略类的不同而变化:9101681487159612101010101010101010注意这个不能用于生产!!!优缺点策略模型的优缺点:消除if-else语句,不同策略相互隔离,易于维护和切换,自由扩展,实现接口。策略模型的缺点:一旦策略过多,维护起来会相对困难,重用代码也比较困难。所有的策略类都暴露给外界。虽然通过Context上下文调用策略模式比较常见,但是有些同学可能会混淆策略模式和状态模式:与状态模式相比:策略模式只会执行一次方法,而状态模式会继续执行状态改变时执行状态改变方式比如我们从A地到B地,策略是飞机或者火车,状态模式就是我们可能去到某个地方,换一种交通方式,换另一种交通方式在另一个地方。总结策略模式比较常用。核心是隔离不同的策略,将具体的算法封装在策略中,抽象出一个策略抽象类,在上下文类中注入不同的具体策略类,从而达到选择不同策略的目的。但是,如果策略很多,就需要考虑重用。当策略类对外暴露时,需要考虑被滥用的风险,会破坏封装。【作者简介】:公众号【秦淮杂货铺】作者秦淮,个人网站:http://aphysia.cn,技术之路不一时,山高水长,哪怕再慢,也不会停下。设计模式系列:设计模式【1】--单例模式有几种写法?设计模式【1.1】——你想如何打破单例模式?设计模式【1.2】--枚举单例这么好用?设计模式[1.3]--Hungry式单例为什么是线程安全的?设计模式[2]--看简单工厂模式?设计模式[2.1]--简单工厂模式是如何演变成工厂方法模式的?设计模式[2.2]--工厂模式是如何演变成抽象工厂模式的?设计模式[3.1]--浅谈代理模式之静态、动态、cglib代理设计模式[3.2]--JDK动态代理源码解析有多香?设计模式[3.3]--CGLIB动态代理源码解释设计模式[4]--建造者模式设计模式详解[5]--原型模式设计模式[6.1]--适配器模式设计模式初探[6.2]]--浅谈适配器模式设计模式[7]--探究桥接模式设计模式[8]--手把手教我写装饰器模式设计模式[9]--外观模式?设计模式上没那么高大上【10】——顺便看看享元模式设计模式【11】——搞定组合模式