场景
策略模式(Strategy Pattern)
是指定义了算法家族并分别封装起来,让它们之间可以互相替换,
此模式使得算法的变化不会影响使用算法的用户。
策略模式的应用场景
1、系统中有很多类,而它们的区别仅仅在于行为不同。
2、一个系统需要动态地在几种算法中选择一种。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
业务举例-物流策略选择
在某物流管理系统中,车辆有人车、料车、皮卡车辆类型,三种车型分别有不同的物流规则。
调度员需要根据不同的货物制定不同的物流方案。
新建物流规则接口LogisticRules
package com.ruoyi.demo.designPattern.strategyPattern; /** * 物流规则类 */ public interface LogisticsRules { //执行物流 void doLogistics(); }
然后分别新建人车、料车、皮卡物流规则类
人车物流规则类
package com.ruoyi.demo.designPattern.strategyPattern; public class PersonCarLogisticsRules implements LogisticsRules{ @Override public void doLogistics() { System.out.println("人车执行物流规则"); } }
料车物流规则类
package com.ruoyi.demo.designPattern.strategyPattern; public class SkipCatLogisticsRules implements LogisticsRules{ @Override public void doLogistics() { System.out.println("料车执行物流规则"); } }
皮卡车物流规则类
package com.ruoyi.demo.designPattern.strategyPattern; public class PickupCarLogisticsRules implements LogisticsRules{ @Override public void doLogistics() { System.out.println("皮卡车执行物流规则"); } }
创建物流方案类
package com.ruoyi.demo.designPattern.strategyPattern; /** * 物流方案类 */ public class LogisticsPlan { private LogisticsRules logisticsRules; public LogisticsPlan(LogisticsRules logisticsRules){ this.logisticsRules = logisticsRules; } public void execute(){ logisticsRules.doLogistics(); } }
编写客户端测试类
package com.ruoyi.demo.designPattern.strategyPattern; import org.apache.commons.lang.StringUtils; public class logicticsTest { public static void main(String[] args) { //游客物流计划 LogisticsPlan visitorPlan = new LogisticsPlan(new PersonCarLogisticsRules()); //快递物流计划 LogisticsPlan expressPlan = new LogisticsPlan(new SkipCatLogisticsRules()); visitorPlan.execute(); expressPlan.execute(); } }
在实际业务中,往往会根据不同的需求对物流规则进行动态选择,代码通常如下
//实际业务中会根据不同的需求对物流规则进行动态选择 LogisticsPlan logisticsPlan = null; String logisticsKey = "EXPRESS"; if(StringUtils.equals(logisticsKey,"EXPRESS")){ logisticsPlan = new LogisticsPlan(new SkipCatLogisticsRules()); }else if(StringUtils.equals(logisticsKey,"VISITOR")){ logisticsPlan = new LogisticsPlan(new PersonCarLogisticsRules()); } logisticsPlan.execute();
这样改造之后,如果经过业务积累,物流规则越来越多,每次上新规则都要改代码、重复测试。
所以可以结合单例模式和工厂模式进行优化。
设计模式-简单工厂模式、工厂模式、抽象工厂模式在Java中的使用示例:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127539695
设计模式-单例模式-饿汉式单例模式、懒汉式单例模式、静态内部类在Java中的使用示例:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127555096
创建LogisticsRulesFactory
package com.ruoyi.demo.designPattern.strategyPattern; import java.util.HashMap; import java.util.Map; public class LogisticsRulesFactory { private static Map<String,LogisticsRules> LOGISTICS_RULES_MAP = new HashMap<>(); static { LOGISTICS_RULES_MAP.put(LogisticsKey.EXPRESS,new SkipCatLogisticsRules()); LOGISTICS_RULES_MAP.put(LogisticsKey.VISTOR,new PersonCarLogisticsRules()); } //默认规则是皮卡车规则-既能拉人、又能拉货 private static final LogisticsRules DEFAULT_RULES = new PickupCarLogisticsRules(); private LogisticsRulesFactory(){} public static LogisticsRules getLogsiticsRules(String logisticsKey){ LogisticsRules logisticsRules = LOGISTICS_RULES_MAP.get(logisticsKey); return logisticsRules == null?DEFAULT_RULES:logisticsRules; } private interface LogisticsKey{ String VISTOR = "VISTOR"; String EXPRESS = "EXPRESS"; } }
这时候客户端代码可以这样写
package com.ruoyi.demo.designPattern.strategyPattern; public class logisticsBetterTest { public static void main(String[] args) { String logisticsKey = "EXPRESS"; LogisticsPlan logisticsPlan = new LogisticsPlan(LogisticsRulesFactory.getLogsiticsRules(logisticsKey)); logisticsPlan.execute(); } }
业务示例-支付方式选择
支付时会选择支付方式,如果未选择,也会用默认的支付方式进行结算。
创建Payment抽象类,定义支付规范和支付逻辑
package com.ruoyi.demo.designPattern.strategyPattern; public abstract class Payment { //支付类型(名称) public abstract String getName(); //查询余额 protected abstract double queryBalance(String uid); //扣款支付 public PayState pay(String uid,double amount){ if(queryBalance(uid)<amount){ return new PayState(500,"支付失败","余额不足"); } return new PayState(200,"支付成功","支付金额:"+amount); } }
分别创建具体的支付方式。
支付宝支付方式
package com.ruoyi.demo.designPattern.strategyPattern; public class AliPay extends Payment{ @Override public String getName() { return "支付宝"; } @Override protected double queryBalance(String uid) { return 900; } }
微信支付类
package com.ruoyi.demo.designPattern.strategyPattern; public class WechatPay extends Payment{ @Override public String getName() { return "微信支付"; } @Override protected double queryBalance(String uid) { return 600; } }
银联支付类
package com.ruoyi.demo.designPattern.strategyPattern; public class UnionPay extends Payment{ @Override public String getName() { return "银联支付"; } @Override protected double queryBalance(String uid) { return 1000; } }
创建支付状态的包装类
package com.ruoyi.demo.designPattern.strategyPattern; public class PayState { private int code; private Object data; private String msg; public PayState(int code, Object data, String msg) { this.code = code; this.data = data; this.msg = msg; } public String toString(){ return ("支付状态:["+code+"],"+msg+",交易详情:"+data); } }
创建支付策略管理类
package com.ruoyi.demo.designPattern.strategyPattern; import java.util.HashMap; import java.util.Map; /** * 支付策略管理类 */ public class PayStrategy { public static final String ALI_PAY = "ALI_PAY"; public static final String WECHAT_PAY = "WECHAT_PAY"; public static final String UNION_PAY = "UNION_PAY"; public static final String DEFAULT_PAY = "UNION_PAY"; private static Map<String,Payment> payStrategy = new HashMap<>(); static { payStrategy.put(ALI_PAY,new AliPay()); payStrategy.put(WECHAT_PAY,new WechatPay()); payStrategy.put(UNION_PAY,new UnionPay()); } public static Payment get(String payKey){ if(!payStrategy.containsKey(payKey)){ return payStrategy.get(DEFAULT_PAY); } return payStrategy.get(payKey); } }
创建订单类
package com.ruoyi.demo.designPattern.strategyPattern; public class Order { private String uid; private String orderId; private double amount; public Order(String uid, String orderId, double amount) { this.uid = uid; this.orderId = orderId; this.amount = amount; } public PayState pay(String payKey){ Payment payment = PayStrategy.get(payKey); System.out.println("欢迎使用"+payment.getName()); System.out.println("本次交易金额为:"+amount+",开始扣款。。。"); return payment.pay(uid,amount); } }
测试代码如下
package com.ruoyi.demo.designPattern.strategyPattern; public class PayStrategyTest { public static void main(String[] args) { Order order = new Order("001","2022103119105523",288.33); //开始支付,选择支付方式,每个渠道的具体算法是不一样的,基本算法是固定的 //在支付的时候才决定这个值用哪个 System.out.println(order.pay(PayStrategy.ALI_PAY)); } }
策略模式的优缺点
优点:
1、策略模式符合开闭原则。
2、策略模式可避免使用多重条件语句,如if...else语句、switch语句。
3、使用策略模式可以提高算法的保密性和安全性。
缺点:
1、客户端必须知道所有的策略,并且决定使用哪一个策略类。
2、代码中会产生非常多的策略类,增加了代码的维护难度。
标签:Java,String,示例,com,package,new,设计模式,strategyPattern,public From: https://www.cnblogs.com/badaoliumangqizhi/p/16845578.html