• 【设计模式】【第四章】【订单状态流转】【状态模式 + 享元模式+模板方法模式】


    创建design-demo项目

    项目代码:https://gitee.com/java_wxid/java_wxid/tree/master/demo/design-demo
    项目结构如下(示例):
    在这里插入图片描述

    创建OrderController

    代码如下(示例):

    package com.example.designdemo.controller;
    
    import com.example.designdemo.order.pojo.Order;
    import com.example.designdemo.pay.pojo.PayBody;
    import com.example.designdemo.service.OrderService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description: 订单管理,这里简单写写,主要是设计模式,别抠细节
     */
    @RestController
    public class OrderController {
        @Autowired
        private OrderService orderService;
    
        @GetMapping("mkOrder")
        public Order createOrder(@RequestParam Integer oid) {
            return orderService.createOrder(oid);
        }
    
        @PostMapping("/pay")
        public Order payOrder(@RequestBody PayBody payBody){
            return orderService.pay(payBody);
        }
    
        @GetMapping("/send")
        public Order send(@RequestParam Integer oid) {
            return orderService.send(oid);
        }
    
        @GetMapping("/receive")
        public Order receive(@RequestParam Integer oid) {
            return orderService.receive(oid);
        }
    }
    
    

    创建OrderService

    代码如下(示例):

    package com.example.designdemo.service;
    
    import com.example.designdemo.order.pojo.Order;
    import com.example.designdemo.pay.pojo.PayBody;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 9:28
     * @Description:
     */
    public interface OrderService {
    
        Order createOrder(Integer oid);
    
        Order pay(PayBody payBody);
    
        Order send(Integer oid);
    
        Order receive(Integer oid);
    }
    
    

    创建OrderServiceImpl

    代码如下(示例):
    package com.example.designdemo.service.impl;

    import com.example.designdemo.order.auditlog.OrderLogProcessor;
    import com.example.designdemo.order.auditlog.PayLogProcessor;
    import com.example.designdemo.order.pojo.Order;
    import com.example.designdemo.order.pojo.OrderState;
    import com.example.designdemo.order.pojo.OrderStateChangeAction;
    import com.example.designdemo.pay.facade.StrategyFacade;
    import com.example.designdemo.pay.pojo.PayBody;
    import com.example.designdemo.service.OrderService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.messaging.Message;
    import org.springframework.messaging.support.MessageBuilder;
    import org.springframework.statemachine.StateMachine;
    import org.springframework.statemachine.persist.StateMachinePersister;
    import org.springframework.stereotype.Service;
    import java.util.ArrayList;
    import java.util.List;
    /**

    • @Author: zhiwei Liao

    • @Date: 2022/9/26 21:29

    • @Description:
      */
      @Service
      public class OrderServiceImpl implements OrderService {

      @Autowired
      private StateMachine orderStateMachine;

      @Autowired
      private StateMachinePersister stateMachinePersister;

      @Autowired
      private PayLogProcessor payLogProcessor;

      @Autowired
      private OrderLogProcessor orderLogProcessor;

      //模拟一个存储
      private List orders = new ArrayList<>();

      public Order createOrder(Integer oid) {
      Order order = new Order();
      order.setOrderState(OrderState.ORDER_WAIT_PAY);
      order.setOrderId(oid);
      // 创建的order是不是得入库啊?如果不入库,下次访问的时候,是不是找不到了啊。
      orders.add(order); // 模拟存储到 db
      orderLogProcessor.processAuditLog(“acccount”, “createOrder”, oid.toString());
      return order;
      }

      // 将来我们删除或者增加或者修改任何关于付款的模块,无需改动service。
      //不会对调用层产生任何代码的改动。
      // 调用层使用我们的pay 模块,无需关系实现的逻辑,只需要将入参传给我们的pay模块即可。
      public Order pay(PayBody payBody) {
      // 书写我们的付款逻辑
      boolean flag = false;
      flag = StrategyFacade.pay(payBody);
      if(flag) {
      Order order = (Order) orders.get(0); // 模拟查询db代码
      payLogProcessor.processAuditLog(payBody.getAccount(), “pay”, order.getOrderId().toString());
      Message message = MessageBuilder
      .withPayload(OrderStateChangeAction.PAY_ORDER).setHeader(“order”, order).build();
      //发送消息,发送给谁?和状态机有没有关系啊? 有
      if(changeStateAction(message,order)) {
      return order;
      }
      //如果是 true,我们要保存到db
      saveToDb(payBody);
      }
      return null;
      }
      private void saveToDb(PayBody payBody) {
      }

      public Order send(Integer oid) {
      Order order = (Order) orders.get(0); // 模拟查询db代码
      Message message = MessageBuilder
      .withPayload(OrderStateChangeAction.SEND_ORDER).setHeader(“order”, order).build();
      if(changeStateAction(message,order)) {
      return order;
      }
      return null;
      }

      public Order receive(Integer oid) {
      Order order = (Order) orders.get(0); // 模拟查询db代码
      Message message = MessageBuilder
      .withPayload(OrderStateChangeAction.RECEIVE_ORDER).setHeader(“order”, order).build();
      if(changeStateAction(message,order)) {
      return order;
      }
      return null;
      }

      private boolean changeStateAction(Message message, Order order) {
      try {
      orderStateMachine.start();
      stateMachinePersister.restore(orderStateMachine, order); // 待议
      boolean res = orderStateMachine.sendEvent(message);
      stateMachinePersister.persist(orderStateMachine, order); // 持久
      return res;
      } catch (Exception e) {
      e.printStackTrace();
      } finally {
      orderStateMachine.stop();
      }
      return false;
      }
      }

    创建AbstractAuditLogProcessor

    代码如下(示例):

    package com.example.designdemo.order.auditlog;
    
    import com.example.designdemo.order.auditlog.pojo.AuditLog;
    
    import java.util.Date;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:
     */
    public abstract class AbstractAuditLogProcessor {
        // 创建我们的 AuditLog (基础部分)
        public final AuditLog buildAuditLog(String account, String action, String orderId){
            AuditLog auditLog = new AuditLog();
            auditLog.setAccount(account);
            auditLog.setAction(action);
            auditLog.setOrderId(orderId);
            auditLog.setDate(new Date());
            return auditLog;
        }
    
        protected abstract AuditLog buildDetails(AuditLog auditLog);
    
        public final void sendToQueue(AuditLog auditLog) {
            //send toQueue(auditLog)
        }
    
        public final void processAuditLog(String account, String action, String orderId) {
            this.sendToQueue(buildDetails(buildAuditLog(account, action, orderId)));
        }
    }
    
    

    创建AuditLog

    代码如下(示例):
    package com.example.designdemo.order.auditlog.pojo;

    import java.util.Date;
    /**

    • @Author: zhiwei Liao

    • @Date: 2022/9/26 21:29

    • @Description:
      */
      public class AuditLog {
      private String account;
      private String action;
      private Date date;
      private String orderId;
      private Object details; //订单创建需要有相关产品信息;
      // 订单支付需要有相关产品信息以及支付方式和支付金额。

      public String getAccount() {
      return account;
      }

      public void setAccount(String account) {
      this.account = account;
      }

      public String getAction() {
      return action;
      }

      public void setAction(String action) {
      this.action = action;
      }

      public Date getDate() {
      return date;
      }

      public void setDate(Date date) {
      this.date = date;
      }

      public String getOrderId() {
      return orderId;
      }

      public void setOrderId(String orderId) {
      this.orderId = orderId;
      }

      public Object getDetails() {
      return details;
      }

      public void setDetails(Object details) {
      this.details = details;
      }

      @Override
      public String toString() {
      return “AuditLog{” +
      “account='” + account + ‘’’ +
      “, action='” + action + ‘’’ +
      “, date=” + date +
      “, orderId='” + orderId + ‘’’ +
      “, details=” + details +
      ‘}’;
      }
      }

    创建LoginLogProcessor

    代码如下(示例):

    package com.example.designdemo.order.auditlog;
    
    import com.example.designdemo.order.auditlog.pojo.AuditLog;
    import org.springframework.stereotype.Component;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:
     */
    @Component
    public class LoginLogProcessor extends AbstractAuditLogProcessor{
        @Override
        protected AuditLog buildDetails(AuditLog auditLog) {
            return auditLog;
        }
    }
    
    

    创建OrderLogProcessor

    代码如下(示例):

    package com.example.designdemo.order.auditlog;
    
    import com.example.designdemo.order.auditlog.pojo.AuditLog;
    import org.springframework.stereotype.Component;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:
     */
    @Component
    public class OrderLogProcessor extends AbstractAuditLogProcessor{
        @Override
        protected AuditLog buildDetails(AuditLog auditLog) {
            String orderId = auditLog.getOrderId();
            String productDetails = "通过 orderId 获取";
            auditLog.setDetails(productDetails);
            System.out.println(auditLog);
            return auditLog;
        }
    }
    
    

    创建PayLogProcessor

    代码如下(示例):

    package com.example.designdemo.order.auditlog;
    
    import com.example.designdemo.order.auditlog.pojo.AuditLog;
    import org.springframework.stereotype.Component;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:
     */
    @Component
    public class PayLogProcessor extends AbstractAuditLogProcessor{
        @Override
        protected AuditLog buildDetails(AuditLog auditLog) {
            String orderId = auditLog.getOrderId();
            String allDetails = "通过 orderId 或者是参数 获取产品信息,金额,支付方式";
            auditLog.setDetails(allDetails);
            System.out.println(auditLog);
            return auditLog;
        }
    }
    
    

    创建Order

    代码如下(示例):

    package com.example.designdemo.order.pojo;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:状态转化的一个控制机。状态机:初始化状态;配置我们的所有状态之间的转化关系;一些持久化的工作(redis)。
     */
    public class Order {
        private Integer orderId;
        private OrderState orderState;//订单状态
    
        public Integer getOrderId() {
            return orderId;
        }
    
        public void setOrderId(Integer orderId) {
            this.orderId = orderId;
        }
    
        public OrderState getOrderState() {
            return orderState;
        }
    
        public void setOrderState(OrderState orderState) {
            this.orderState = orderState;
        }
    }
    
    

    创建OrderState

    代码如下(示例):

    package com.example.designdemo.order.pojo;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:订单状态
     */
    public enum  OrderState {
        ORDER_WAIT_PAY, // 待支付
        ORDER_WAIT_SEND, // 待发货
        ORDER_WAIT_RECEIVE, // 待收货
        ORDER_FINISH; // 完成订单
    }
    
    

    创建OrderStateChangeAction

    代码如下(示例):

    package com.example.designdemo.order.pojo;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:订单状态操作
     */
    public enum OrderStateChangeAction {
        PAY_ORDER, // 支付操作
        SEND_ORDER, // 发货操作
        RECEIVE_ORDER; // 收货操作
    }
    
    

    创建OrderStateMachineConfig

    代码如下(示例):

    package com.example.designdemo.order.config;
    
    import com.example.designdemo.order.pojo.Order;
    import com.example.designdemo.order.pojo.OrderState;
    import com.example.designdemo.order.pojo.OrderStateChangeAction;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.statemachine.StateMachineContext;
    import org.springframework.statemachine.StateMachinePersist;
    import org.springframework.statemachine.config.EnableStateMachine;
    import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
    import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
    import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
    import org.springframework.statemachine.persist.DefaultStateMachinePersister;
    import org.springframework.statemachine.support.DefaultStateMachineContext;
    import java.util.EnumSet;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:
     */
    @Configuration
    @EnableStateMachine(name="orderStateMachine")
    public class OrderStateMachineConfig extends StateMachineConfigurerAdapter {
        public void configure(StateMachineStateConfigurer states) throws Exception {
            states.withStates().initial(OrderState.ORDER_WAIT_PAY)
                    .states(EnumSet.allOf(OrderState.class));
        }
    
        public void configure(StateMachineTransitionConfigurer transitions) throws Exception {
            transitions.withExternal().source(OrderState.ORDER_WAIT_PAY)
                    .target(OrderState.ORDER_WAIT_SEND)
                    .event(OrderStateChangeAction.PAY_ORDER)
                    .and()
                    .withExternal().source(OrderState.ORDER_WAIT_SEND)
                    .target(OrderState.ORDER_WAIT_RECEIVE)
                    .event(OrderStateChangeAction.SEND_ORDER)
                    .and()
                    .withExternal().source(OrderState.ORDER_WAIT_RECEIVE)
                    .target(OrderState.ORDER_FINISH)
                    .event(OrderStateChangeAction.RECEIVE_ORDER);
        }
    
        // 配置状态机持久化
        @Bean
        public DefaultStateMachinePersister machinePersister() {
            return new DefaultStateMachinePersister<>(new StateMachinePersist() {
    
                @Override
                public void write(StateMachineContext stateMachineContext, Order order) throws Exception {
                    //持久化操作。可以通过任何形式进行持久化。redis 、 mongodb、mysql,ecache
                }
    
                @Override
                public StateMachineContext read(Order order) throws Exception {
                    // 本来是应该从持久化组件里进行读取的。但是没做持久化
                    return new DefaultStateMachineContext(order.getOrderState(), null, null, null);
                }
            });
        }
    }
    
    

    创建OrderStateListener

    代码如下(示例):

    package com.example.designdemo.order.listener;
    
    import com.example.designdemo.order.pojo.Order;
    import com.example.designdemo.order.pojo.OrderState;
    import com.example.designdemo.order.pojo.OrderStateChangeAction;
    import org.springframework.messaging.Message;
    import org.springframework.statemachine.annotation.OnTransition;
    import org.springframework.statemachine.annotation.WithStateMachine;
    import org.springframework.stereotype.Component;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/26 21:29
     * @Description:监听器是监听到 action 后进行状态的一个变更。
     */
    @Component("orderStateListener")
    @WithStateMachine(name="orderStateMachine")
    public class OrderStateListener {
        @OnTransition(source = "ORDER_WAIT_PAY", target = "ORDER_WAIT_SEND")
        public boolean payToSend(Message message){
            Order order = (Order) message.getHeaders().get("order");
            order.setOrderState(OrderState.ORDER_WAIT_SEND);
            return true;
        }
        @OnTransition(source = "ORDER_WAIT_SEND", target = "ORDER_WAIT_RECEIVE")
        public boolean sendToReceive(Message message){
            Order order = (Order) message.getHeaders().get("order");
            order.setOrderState(OrderState.ORDER_WAIT_RECEIVE);
            return true;
        }
        @OnTransition(source = "ORDER_WAIT_RECEIVE", target = "ORDER_FINISH")
        public boolean receiveToFinish(Message message){
            Order order = (Order) message.getHeaders().get("order");
            order.setOrderState(OrderState.ORDER_FINISH);
            return true;
        }
    
    }
    
    

    创建StrategyFacade

    代码如下(示例):

    package com.example.designdemo.pay.facade;
    
    import com.example.designdemo.pay.additionalDecorator.AddFuncDecorator;
    import com.example.designdemo.pay.context.PayContext;
    import com.example.designdemo.pay.factory.AddFuncFactory;
    import com.example.designdemo.pay.factory.PayFactory;
    import com.example.designdemo.pay.strategy.PayStrategy;
    import com.example.designdemo.pay.factory.StrategyFactory;
    import com.example.designdemo.pay.pojo.PayBody;
    import com.example.designdemo.pay.strategyEnum.StrategyEnum;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 11:27
     * @Description: 门面模式,最终只暴露门面即可,门面就是我们的超级封装
     */
    
    public class StrategyFacade {
    
        // 定义一个map,将对应关系提前初始化好。
        // 双十一的时候,有大量的用户进行下单(千万级),就会造成千万级的pay接口的调用。
        // 很可惜,这部分代码里边有两个 new 关键字(new PayContext(payStrategy) 和 new AddFuncDecorator)。
        // 如果瞬时见。有几十万的并发进来,那么会创建几十万个 context对象和 addFunc对象,造成 年轻代的eden区的频繁对象创建
        // 虽然说调用完就进行了对象的垃圾收集,但是这么多的访问对象进来会造成,minorgc。
        // 1. 单例模式吗?PayContext创建是基于payStrategy,不止一种paycontext啊,用单例不行呀。 AddFuncDecorator 是基于PayContext
        // 创建的,PayContext 不止一种,AddFuncDecorator 也不止一种。
        // 2. 享元模式。享元模式是单例模式的一种思想升级。单例模式,针对的是同一种对象,没有任何不同的细节。而享元模式,针对多个对象。
        // 多个对象:同一种class,但是里边的属性有些许不同。PayContext是同一种对象吧?是的; PayContext 是不是有细节上的不同呢?是的,
        // payStrategy不同; 那么我们是否可以知道这个PayContext的种类数量呢?是的,目前有三种。 享元模式能够对这可控数量的有不同细节的
        //同一种class对象进行共享,保证我们的程序不频繁的创建对象。
        public static Boolean pay(PayBody payBody) {
            //获取我们的 策略枚举
            StrategyEnum strategyEnum = getStrategyEnum(payBody.getType());
            if(strategyEnum == null) {
                return false;
            }
            //获取我们的策略对象
            PayStrategy payStrategy = StrategyFactory.getPayStrategy(strategyEnum);
            //生成我们的策略上下文
            PayContext context = PayFactory.getPayContext(payStrategy); // 享元模式解决高并发下频繁创建对象的问题
            // 装饰一下 context,。立马多了一个功能
            // 我看这行代码啊,就不顺眼。代理模式搞他。
            AddFuncDecorator addFuncDecorator = (AddFuncDecorator) AddFuncFactory.getAddFunc(context); // 享元模式解决高并发下频繁创建对象的问题
            //进行扣款
            return addFuncDecorator.execute(payBody);
        }
    
        private static StrategyEnum getStrategyEnum(int type) {
            switch (type) {
                case 0:
                    return StrategyEnum.ZfbPayStrategy;
                case 1:
                    return StrategyEnum.WxPayStrategy;
                case 2:
                    return StrategyEnum.BankPayStrategy;
                default:
                    return null;
            }
        }
    
    }
    
    

    创建AddFuncFactory

    代码如下(示例):

    package com.example.designdemo.pay.factory;
    
    import com.example.designdemo.pay.additionalDecorator.AbstractAddFuncDecorator;
    import com.example.designdemo.pay.additionalDecorator.AddFuncDecorator;
    import com.example.designdemo.pay.context.PayContext;
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 20:53
     * @Description:
     */
    public class AddFuncFactory {
        // 工厂的目的是生产 AddFuncDecorator; 生产几个啊? 多个:享元
        // key 应该是能够和 AbstractAddFuncDecorator 做成对应的东西。
        // 这个map最多保存是三个对象。
        public final static Map maps = new ConcurrentHashMap<>();
    
        public static AbstractAddFuncDecorator getAddFunc(PayContext payContext) {
            if(maps.get(payContext) == null) {
                AddFuncDecorator addFuncDecorator = new AddFuncDecorator(payContext);
                maps.put(payContext, addFuncDecorator);
            }
            return maps.get(payContext);
        }
    }
    
    

    创建PayFactory

    代码如下(示例):

    package com.example.designdemo.pay.factory;
    
    
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import com.example.designdemo.pay.context.PayContext;
    import com.example.designdemo.pay.strategy.PayStrategy;
    
    /**
     * @author zhiweiLiao
     * @Description 享元模式解决高并发下频繁创建对象的问题
     * @Date create in 2022/9/28 0028 13:57
     */
    public class PayFactory {
    
        public final static Map maps = new ConcurrentHashMap<>();
    
        public static PayContext getPayContext(PayStrategy payStrategy) {
            if(maps.get(payStrategy) == null) {
                PayContext payContext = new PayContext(payStrategy);
                maps.put(payStrategy, payContext);
            }
            return maps.get(payStrategy);
        }
    
    }
    
    

    创建StrategyFactory

    代码如下(示例):

    package com.example.designdemo.pay.factory;
    
    import com.example.designdemo.pay.strategy.PayStrategy;
    import com.example.designdemo.pay.strategyEnum.StrategyEnum;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 10:53
     * @Description: 策略工厂 工厂类依靠策略枚举返回策略类 后面都不需要修改了,因为它是一个无状态的 使用饿汉单例模式创建
     */
    
    public class StrategyFactory {
    
        private static final Map strategyMaps = new ConcurrentHashMap();
    
        public static PayStrategy getPayStrategy(StrategyEnum strategyEnum){
            PayStrategy payStrategy = strategyMaps.get(strategyEnum.getValue());
            try {
                payStrategy = (PayStrategy) Class.forName(strategyEnum.getValue()).newInstance();
                strategyMaps.put(strategyEnum.getValue(), payStrategy);
            } catch (Exception e) {
                //异常信息打印
            }
            return payStrategy;
        }
    
    }
    
    

    创建AddFuncDecorator

    代码如下(示例):

    package com.example.designdemo.pay.additionalDecorator;
    
    import com.example.designdemo.pay.context.AbstractPayContext;
    import com.example.designdemo.pay.pojo.PayBody;
    
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 20:53
     * @Description:abstractPayContext 不是共享的,因为有的小伙伴选择 zfb 支付,有的小伙伴选择wx支付,等等。。。
     */
    public class AddFuncDecorator extends AbstractAddFuncDecorator{
        public AddFuncDecorator(AbstractPayContext abstractPayContext) {
            super(abstractPayContext);
        }
    
        // 新活儿
        @Override
        public void additionalFunction(PayBody payBody) { // 共享的,跟支付策略没有任何关系
            String product = payBody.getProduct();
            // 从db里边获取 product的详细信息。
            // 从配置中心(redis缓存)里获取产品的更新策略。
            // 根据策略更新用户平台币 或(和) 发放红包。
            System.out.println("更新平台币成功,发送红包到用户优惠券模块成功。");
        }
    
        @Override
        public Boolean execute(PayBody payBody) { // 算共享的。共享的调用逻辑
            Boolean result = super.execute(payBody); //老活儿
            this.additionalFunction(payBody); // 新活儿. 新活儿的各种重试,失败补偿
            return result;
        }
    
    }
    
    

    创建AbstractAddFuncDecorator

    代码如下(示例):

    package com.example.designdemo.pay.additionalDecorator;
    
    
    import com.example.designdemo.pay.context.AbstractPayContext;
    import com.example.designdemo.pay.pojo.PayBody;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 20:53
     * @Description:
     */
    public abstract class AbstractAddFuncDecorator extends AbstractPayContext {
        // 这是我们的装饰器类。专门干装修的。 专门添加新功能的(平台币,红包)
        // 装饰的是谁啊? 我作为一个称职的装饰器,我必须得知道装饰的是谁,不然我咋干活儿啊。
        private AbstractPayContext abstractPayContext = null;
    
        public AbstractAddFuncDecorator(AbstractPayContext abstractPayContext) {
            this.abstractPayContext = abstractPayContext;
        }
    
        // 开始干活儿
        //1. 老活儿。 支付。但是我又不能修改支付代码,也不能修改支付逻辑。
        @Override
        public Boolean execute(PayBody payBody) {
            return abstractPayContext.execute(payBody);
        }
    
        //2. 老活儿不合适,没你装饰器照样能execute。 新活儿:平台币,红包)
        public abstract void additionalFunction(PayBody payBody);
    }
    

    创建StrategyEnum

    代码如下(示例):

    package com.example.designdemo.pay.strategyEnum;
    /**
     * @Author: zhiwei Liao
     * @Date: 2022/9/25 10:56
     * @Description: 准备使用反射
     */
    
    public enum StrategyEnum {
    
        ZfbPayStrategy("com.example.designdemo.pay.strategy.ZfbPayStrategy"),
        WxPayStrategy("com.example.designdemo.pay.strategy.WxPayStrategy"),
        BankPayStrategy("com.example.designdemo.pay.strategy.BankPayStrategy");
    
        String value = "";
    
        StrategyEnum(String value){
            this.value = value;
        }
    
        public String getValue(){
            return this.value;
        }
    }
    
    

    校验是否正常工作

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    linux笔记(3):东山哪吒STU开发板初体验
    Spring核心扩展点BeanDefinitionRegistryPostProcessor源码分析
    npm install:sill idealTree buildDeps
    springboot基于web的传染病信息管理系统的设计与实现毕业设计-附源码221124
    【软考篇】中级软件设计师 第四部分(三)
    Python OpenCV 视频抽帧处理并保存
    Knife4j_接口概述、常用注解详解、搭建swagger项目、功能概述
    Linux常用命令
    前端周刊第十四期
    基于SSM的租房管理系统
  • 原文地址:https://blog.csdn.net/java_wxid/article/details/127088117