首页 / 资讯中心 / 文章详情

【架构-设计模式】----一篇文章搞定策略模式,轻松易懂

【架构-设计模式】----一篇文章搞定策略模式,轻松易懂 ★ FEATURED ARTICLE
一篇文章搞定策略模式轻松易懂一、什么是策略模式策略模式Strategy Pattern定义一系列可互换的算法策略把每个算法封装成独立类让算法和使用算法的代码解耦算法可以动态替换。核心一句话同一个行为有多种不同实现可以随时切换不用大量if/else。适用场景一堆if-else/switch分支还会不断新增。角色拆解3个策略接口 Strategy统一规范所有策略的方法具体策略 ConcreteStrategy实现接口每种算法单独写一个类上下文 Context持有策略对象对外提供调用入口负责使用策略二、举个生活化例子场景商场结算不同会员折扣不一样普通会员无折扣银卡会员9折金卡会员8折以后还可能新增钻石会员、限时折扣。❌ 坏写法大量if elsepublicdoublecalcPrice(doubleoriginPrice,StringmemberType){if(普通.equals(memberType)){returnoriginPrice;}elseif(银卡.equals(memberType)){returnoriginPrice*0.9;}elseif(金卡.equals(memberType)){returnoriginPrice*0.8;}returnoriginPrice;}缺点新增折扣要改这个方法违反开闭原则if越来越臃肿。✅ 策略模式改造1. 策略接口// 折扣策略接口publicinterfaceDiscountStrategy{// 计算折扣后价格doublegetPrice(doubleoriginPrice);}2. 具体策略类// 普通会员publicclassNormalStrategyimplementsDiscountStrategy{OverridepublicdoublegetPrice(doubleoriginPrice){returnoriginPrice;}}// 银卡9折publicclassSilverStrategyimplementsDiscountStrategy{OverridepublicdoublegetPrice(doubleoriginPrice){returnoriginPrice*0.9;}}// 金卡8折publicclassGoldStrategyimplementsDiscountStrategy{OverridepublicdoublegetPrice(doubleoriginPrice){returnoriginPrice*0.8;}}3. Context上下文负责持有策略对外提供服务publicclassPriceContext{// 持有策略privateDiscountStrategystrategy;// 构造传入策略publicPriceContext(DiscountStrategystrategy){this.strategystrategy;}// 动态更换策略publicvoidsetStrategy(DiscountStrategystrategy){this.strategystrategy;}// 执行计算publicdoublecalc(doubleoriginPrice){returnstrategy.getPrice(originPrice);}}4. 客户端调用publicclassTest{publicstaticvoidmain(String[]args){// 原价1000doubleprice1000;// 金卡结算PriceContextcontextnewPriceContext(newGoldStrategy());System.out.println(context.calc(price));// 800.0// 动态切换成银卡context.setStrategy(newSilverStrategy());System.out.println(context.calc(price));//900.0}}新增钻石会员只需要新建DiamondStrategy实现接口不用修改原有代码满足开闭原则。三、UML简图文字版DiscountStrategy(接口) ↑ ┌────┬────┬────┐ Normal Silver Gold ↑ PriceContext 持有 DiscountStrategy四、优缺点✅ 优点消除大量if/else、switch算法独立方便单元测试策略可动态切换新增策略不改动旧代码符合开闭原则❌ 缺点策略增多类数量膨胀每一个策略都要新建类客户端需要理解各个策略差异才能选择合适策略五、Java里的实际使用java.util.Comparator就是典型策略接口Collections.sort(list, Comparator)第二个参数就是不同排序策略可以随时更换。线程池拒绝策略RejectedExecutionHandlerAbort、Discard、CallerRuns 都是策略。六、策略模式 VS 简单工厂容易混淆策略侧重行为算法的动态替换算法可运行时切换上下文持有策略简单工厂侧重对象创建根据参数帮你new出对象一般一次性获取经常组合使用工厂 策略工厂根据类型生产对应的策略对象客户端不用自己new策略。七、Lambda简化Java8优化减少类爆炸策略是函数式接口可以不用写一堆策略类直接传lambda// 接口上加 FunctionalInterfaceFunctionalInterfacepublicinterfaceDiscountStrategy{doublegetPrice(doubleoriginPrice);}// 调用PriceContextctxnewPriceContext(p-p*0.7);System.out.println(ctx.calc(1000));适合简单策略复杂策略逻辑多还是单独拆类。八、什么时候选策略模式满足下面任意一条就可以考虑同一个业务多种算法/方案需要互相替换代码充斥大量if else后续分支还会持续增加希望把算法独立出来单独管理、单独测试
阅读完成 · 觉得有帮助?
咨询建站