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

设计模式strategypattern

时间:2023-04-01 16:54:38 Java

在一个收银系统中,如果普通用户、中级会员、高级会员对应不同的优惠政策,常规的编程必须使用一系列的判断语句来判断用户类型。在这种情况下,您可以使用策略模式。1.概念理解策略模式的概念很容易理解。它将对象与行为分离,将行为定义为行为接口和具体行为的实现,每一个if判断都可以理解为一种策略。如果策略模式用在收银系统中,普通会员、中级会员、高级会员分别定义一个具体的策略类,并实现各自的方法,定义一个环境类,持有策略类的引用,并调用相应的通过引用策略类方法,客户端传入对应的具体策略对象,调用各自的策略方法。很多人在学习了statemode之后,也把statemode和statemode搞混了。现在你可以想想为什么不使用状态模式呢?每个策略之间没有转移(例如:状态1234切换)关系,每个算法实现自己的逻辑,客户端控制调用哪个策略。如果用state模式,就变成了,先调用普通会员的策略,再调用中级会员的策略,再调用高级会员的策略,看到最后的优惠用户估计要疯了!和状态模式一样,策略模式也应该包括三个角色:抽象策略类:策略是一个接口,定义了几个算法标识,也就是定义了几个抽象方法具体策略类:具体策略是实现了策略接口的类Environment类/上下文类:上下文提供了一种方法,该方法持有对策略类的引用,并最终由客户端调用。与状态模式相比,策略模式中各个角色的职责更加简单。我们基于收银机案例实现策略模式demo。2.案例实现抽象策略类:定义业务抽象方法,我们主要计算价格/***策略抽象类*@authortcy*@Date21-09-2022*/publicinterfaceAbstractMemberStrategy{//一个计算价格的抽象方法//priceproductpricennumberofproductspublicdoublecalcPrice(doubleprice,intn);}具体策略-高级会员:每个具体策略实现自己的计算方法/**高级会员*@authortcy*@Date21-09-2022*/publicclassStrategyAdvanceMemberimplementsAbstractMemberStrategy{@OverridepublicdoublecalcPrice(doubleprice,intn){doublemoney=price*n*0.8;退钱;}}具体策略-中间成员:/***中间成员*@authortcy*@Date21-09-2022*/publicclassStrategyIntermediateMemberimplementsAbstractMemberStrategy{@OverridepublicdoublecalcPrice(doubleprice,intn){doublemoney=价格*n*0.9;退钱;}}specificStrategy-OrdinaryMember:/***PrimaryMember*@authortcy*@Date21-09-2022*/publicclassStrategyPrimaryMemberimplementsAbstractMemberStrategy{@OverridepublicdoublecalcPrice(doubleprice,intn){返回价格*名词;}}环境类:持有政策策略类的引用,调用时传入对应的具体策略对象,会调用策略的各个方法/**环境类*@authortcy*@Date21-09-2022*/publicclassContext{//用户折扣策略接口privateAbstractMemberStrategymemberStrategy;//注入构造函数publicContext(AbstractMemberStrategymemberStrategy){this.memberStrategy=memberStrategy;}//计算价格publicdoubleqoutePrice(doublegoodsPrice,intn){//通过接口变量调用对应的具体策略returnmemberStrategy.calcPrice(goodsPrice,n);}}客户端调用:/***@authortcy*@Date21-09-2022*/publicclassClient{publicstaticvoidmain(String[]args){//工具策略类AbstractMemberStrategyprimaryMemberStrategy=newStrategyPrimaryMember();AbstractMemberStrategyintermediateMemberStrategy=newStrategyIntermediateMember();AbstractMemberStrategyadvanceMemberStrategy=newStrategyAdvanceMember();//用户选择不同的策略ContextprimaryContext=newContext(primaryMemberStrategy);上下文intermediateContext=newContext(intermediateMemberStrategy);语境advanceContext=newContext(advanceMemberStrategy);//100元一本书//普通会员:100System.out.println("普通会员价格:"+primaryContext.qoutePrice(100,1));//中级会员90System.out.println("中级会员价格:"+intermediateContext.qoutePrice(100,1));//高级会员80System.out.println("高级会员价格:"+advanceContext.qoutePrice(100,1));}}策略模式比状态模式更容易理解3、应用策略模式在Jdk中的典型应用是Jdk中线程池满后的拒绝策略。我们在创建线程池时,会传入如下参数:publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler){if(corePoolSize<0||maximumPoolSize<=0||maximumPoolSizeschedule(Runnablecommand,longdelay,TimeUnitunit){if(command==null||unit==null)抛出新的NullPointerException();RunnableScheduledFuturet=decorateTask(command,newScheduledFutureTask(command,null,triggerTime(delay,unit)));延迟执行(t);returnt;}既然是客户端,就会有机会调用拒绝策略方法,我们点进去看看delayedExecute()方法。privatevoiddelayedExecute(RunnableScheduledFuturetask){if(isShutdown())reject(task);else{super.getQueue().add(任务);如果(isShutdown()&&!canRunInCurrentRunState(task.isPeriodic())&&remove(task))task.cancel(false);否则ensurePrestart();}}接下来看reject()方法,适时调用拒绝策略方法。传入对应的this对象,调用不同的拒绝策略。finalvoidreject(Runnablecommand){handler.rejectedExecution(command,this);}调用顺序如下图所示:何时调用哪种拒绝策略由delayedExecute()方法本身决定,每种拒绝策略都有自己的业务逻辑。它是策略模式的典型应用。4.策略模式和状态模式的区别虽然类图和状态模式完全一样,但是很多博主也把它们搞混了。事实上,策略模式和状态模式之间并没有半钱关系。只有了解了两种模式的使用场景,在用到的时候才能游刃有余。以下是我总结的四个不同点。状态模式的博客可以参考状态模式。①策略模型中的策略互不相关,如支付方式选择和优惠政策选择;状态模型往往是一组流程,如订单状态流、请假流程审批等。在状态模式下,客户端只是调用,每个特定的状态类定义下一个状态。③状态模型强调状态变化,策略模型强调策略的选择。5.总结使用策略模式会让我们的代码更加“干净”,但是如果在实际的if判断中逻辑很简单,我们仍然使用策略模式,就变成了设计模式的使用,这无疑会加剧系统的复杂性。就像在商城系统中,微信支付、支付宝支付、银联支付,业务逻辑没有那么简单,使用策略模型是一个不错的选择。总体来说,策略模式是行为模式中比较简单的一种模式。理解和编写都极其简单,其难度堪比结构设计模式中的单例模式。设计模式的研究应该是系统的。我推荐你阅读我过去发表的设计模式文章。1.设计模式概述2.设计模式的工厂方法和抽象工厂3.设计模式的单例和原型4.设计模式的建造者模式5.设计模式的代理模式6.设计模式的适配器模式7.设计模式的桥梁设计模式模式八、组合模式九、设计模式装饰器模式十、设计模式外观模式十一、外观模式享元模式十二、设计模式责任链模式十三、设计模式命令模式十四、设计解释器模式设计模式十五、迭代器模式设计模式十六、设计模式中间模式十七、设计模式备忘录模式十八、设计模式观察者模式十九、设计模式状态模式