2021年4月3日星期六

设计模式-策略模式初体验

设计模式按照功能型分类

创建型模式:

  • 工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式

结构型模式:

  • 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式

行为型模式:

  • 策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

策略模式的定义:

  • 定义了算法族,分别封装起来,让它们直接可以互相替换,此模式让算法的变化独立于使用算法的客户.让算法的变化不会影响算法的用户.

  • 适用场景: 对外提供一个统一的接口,有不同的业务实现,上层不需要关心具体的实现细节,比如支付场景,消息消费场景

  • 可以避免多重分支 if else 或者switch分支

  • 属于行为型模式

适用场景举例:

  • 订单支付场景
/** * 支付订单 */@Data@Accessors(chain = true)public class PayOrder { /**  * 订单号  */ private String orderId; /**  * 支付用户  */ private String userId; /**  * 支付金额  */ private Long payAmount; /**  * 支付渠道  */ private PayChannelEnums payChannel; public PayOrder(String orderId, String userId, Long payAmount, PayChannelEnums payChannel) {  this.orderId = orderId;  this.userId = userId;  this.payAmount = payAmount;  this.payChannel = payChannel; }/** * 支付类型枚举 */public enum PayChannelEnums { /**  * 支付渠道  */ WE_CHAT("wechat", "微信支付"), ALI_PAY("alipay", "支付宝支付"), JD_PAY("jdpay", "京东白条"), UNION_PAY("unionpay", "银联支付"); private String code; private String desc; PayChannelEnums(String code, String desc) {  this.code = code;  this.desc = desc; } public String getCode() {  return code; } public String getDesc() {  return desc; }}/** * 支付接口 */public interface Payment { /**  * 标准支付方法  */ Boolean doPay(PayOrder payOrder); /**  * 校验余额,钩子方法  */ Boolean checkalance(PayOrder payOrder);}/** * 支付宝支付 */public class AliPay implements Payment { static {  System.out.println("欢迎使用阿里支付"); } @Override public Boolean doPay(PayOrder payOrder) {  return true; } @Override public Boolean checkBalance(PayOrder payOrder) {  return payOrder.getPayAmount() > 10; }}/** * 微信支付 */public class WeChatPay implements Payment { static {  System.out.println("欢迎使用微信支付"); } @Override public Boolean doPay(PayOrder payOrder) {  return true; } @Override public Boolean checkBalance(PayOrder payOrder) {  return payOrder.getPayAmount() > 50; }}/** * 默认执行的实现类 */public class DefaultPayment implements Payment { @Override public Boolean doPay(PayOrder payOrder) {  Payment payment = getPaymentByType(payOrder.getPayChannel());  if (payment == null) {   System.out.println("不支持的支付类型");   return false;  }  //校验余额  Boolean checkalance = payment.checkBalance(payOrder);  if (!checkalance) {   System.out.println("您的余额不足,无法支付");   return false;  }  Boolean result = payment.doPay(payOrder);  if (!result) {   System.out.println("支付失败");  } else {   System.out.println("支付成功");  }  return result; } /**  * 获取实际的支付类型,也可以通过spring上下文获取,或者通过bean工厂创建  *  * @param payChannelEnums  * @return  */ private Payment getPaymentByType(PayChannelEnums payChannelEnums) {  try {   if (Objects.equals(payChannelEnums, PayChannelEnums.WE_CHAT)) {    return new WeChatPay();   }   if (Objects.equals(payChannelEnums, PayChannelEnums.ALI_PAY)) {    return new AliPay();   }   if (Objects.equals(payChannelEnums, PayChannelEnums.JD_PAY)) {    return new JdPay();   }   if (Objects.equals(payChannelEnums, PayChannelEnums.UNION_PAY)) {    return new UnionPay();   }  } catch (Exception e) {   e.printStackTrace();  }  return null; } @Override public Boolean checkBalance(PayOrder payOrder) {  return false; }}/** * 支付控制台 */public interface PaymentPlatform { /**  * 订单支付入口  *  * @param payOrder  * @return  */ Boolean orderPay(PayOrder payOrder);}/** * 支付控制台实现类 */public class PaymentPlatformImpl implements PaymentPlatform { @Override public Boolean orderPay(PayOrder payOrder) {  //默认执行的实现类实现,不需要关心支付细节  Payment defaultPayment = new DefaultPayment();  return defaultPayment.doPay(payOrder); }}/** * 执行main方法 */public class MainClass { public static void main(String[] args) {  PayOrder payOrder = new PayOrder("O-0001", "lihua", 20L, PayChannelEnums.ALI_PAY);  PaymentPlatform paymentPlatform = new PaymentPlatformImpl();  paymentPlatform.orderPay(payOrder); }}/** * 控制台输出 */------------------欢迎使用阿里支付支付成功------------------- 

注意点

  • 支付控制台 PaymentPlatform提供了外部访问的标准入口和参数,内部封装了具体的执行细节

  • payment是支付的标准接口,通过DefaultPayment的getPaymentByType方法来实现创建支付bean和调用支付方法,也可以通过bean工厂和spring上下文来创建bean,策略模式一般会结合工厂模式使用

  • doPay是为了方便测试,默认返回了支付结果,在实际支付过程中,支付调用一般是先调用预支付接口获取预支付信息,前端唤起支付后,后端服务通过异步获取第三方支付回调的支付结果

策略模式的优缺点

优点
  • 策略模式复合开闭原则,如果有新的支付算法,只需要实现支付接口,扩展支付的实现就行

  • 避免使用了多条件的if,else,增加了可读性

  • 提高内部算法的保密性和安全性

缺点
  • 客户端调用时必须知道所有的策略,并且自行决定使用哪一个策略
  • 代码中会产生非常多策略类,增加维护难度。








原文转载:http://www.shaoqun.com/a/662721.html

跨境电商:https://www.ikjzd.com/

新单:https://www.ikjzd.com/w/79

智赢:https://www.ikjzd.com/w/1511


设计模式按照功能型分类创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式策略模式的定义:定义了算法族,分别封装起来,让它们直接可以互相替换,此模式让算法的变化
transfer:https://www.ikjzd.com/w/1735
邮乐:https://www.ikjzd.com/w/1776
虚拟信用卡:https://www.ikjzd.com/w/1055
福利干货,申诉模版大全:https://www.ikjzd.com/tl/13079
广告排名:https://www.ikjzd.com/tl/21866
喜获3亿融资!隐形大卖C位出圈:https://www.ikjzd.com/home/132495

没有评论:

发表评论