• Java设计模式 | 基于订单批量支付场景,对策略模式和简单工厂模式进行简单实现


    基于订单批量支付场景,对策略模式和简单工厂模式进行简单实现

    策略模式

    介绍

    以下是菜鸟教程对策略模式的介绍: 策略模式

    在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。

    策略模式主要有三个角色:

    • 抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
    • 具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。
    • 环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。

    实现

    抽象策略

    我们使用接口来实现抽象策略,规定了支付的公共方法,根据传入的用户名和支付金额进行结算。

    package knowledege.designPattern.strategy.test1;
    
    import java.math.BigDecimal;
    
    public interface PayStrategy {
        void pay(String name, BigDecimal money);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    具体策略

    初始化微信和支付宝两种支付策略

    1.AliPayStrategy
    package knowledege.designPattern.strategy.test1;
    
    import java.math.BigDecimal;
    
    public class AliPayStrategy implements PayStrategy{
        @Override
        public void pay(String name, BigDecimal money) {
            System.out.println("[" +name+ "]使用支付宝支付..." + money + "元");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2.WeChatPayStrategy
    package knowledege.designPattern.strategy.test1;
    
    import java.math.BigDecimal;
    
    public class WeChatPayStrategy implements PayStrategy{
        @Override
        public void pay(String name, BigDecimal money) {
            System.out.println("[" +name+ "]使用微信支付..." + money + "元");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    环境

    提供设置策略和执行策略的方法

    package knowledege.designPattern.strategy.test1;
    
    import java.math.BigDecimal;
    public class PayContext {
        private PayStrategy payStrategy;
        public PayContext(){}
        public void setPayStrategy(PayStrategy payStrategy){
            this.payStrategy = payStrategy;
        }
        public void executePayStrategy(String name, BigDecimal money){
            payStrategy.pay(name, money);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用简单工厂来获取具体策略对象

    支付方式枚举

    定义枚举并支持静态根据支付方式获取枚举

    package knowledege.designPattern.strategy.test1;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    
    @Getter
    @AllArgsConstructor
    public enum PayWayEnum {
    
        PAY_ALI("01","支付宝"),
        PAY_WE_CHAT("02","微信");
        public final String payWay;
        public final String payDesc;
    
        public static PayWayEnum getEnumByWay(String payWay){
            for(PayWayEnum enums: PayWayEnum.values()){
                if(enums.payWay.equals(payWay)){
                    return enums;
                }
            }
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    策略工厂接口

    
    public interface StrategyFactory {
        PayStrategy initStrategy();
    }
    
    • 1
    • 2
    • 3
    • 4

    策略工厂实现

    package knowledege.designPattern.strategy.test1;
    
    import java.util.Objects;
    
    public class StrategySimpleFactory {
        public static PayStrategy initStrategy(String payWay){
            PayWayEnum payWayEnum = PayWayEnum.getEnumByWay(payWay);
            if (Objects.isNull(payWayEnum)) {
                return null;
            }
            PayStrategy strategy = null;
            switch (payWayEnum) {
                case PAY_ALI:
                    strategy = new AliPayStrategy();
                    break;
                case PAY_WE_CHAT:
                    strategy = new WeChatPayStrategy();
                    break;
            }
            return strategy;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    测试使用

    订单实体类

    package knowledege.designPattern.strategy.test1;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.math.BigDecimal;
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class OrderTestDTO {
        Integer orderNum;
        String payPersonName;
        String payWay;
        BigDecimal payMoney;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    对订单进行批量支付

    模拟对订单进行批量支付

    • 模拟获取一批订单
    • 循环订单进行支付
      • 根据订单的支付方式,获取支付枚举
      • 根据枚举,使用工厂模式获取支付策略
      • 根据策略,使用支付环境进行支付
    package knowledege.designPattern.strategy.test1;
    
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.List;
    
    public class test1 {
        public static void main(String[] args) {
            List<OrderTestDTO> orderList = initOrders();
            batchPay(orderList);
        }
    
        /**
         * 获取订单
         */
        public static  List<OrderTestDTO> initOrders(){
            List<OrderTestDTO> orderList = new ArrayList<>();
            orderList.add(new OrderTestDTO(1,"aaa","01",new BigDecimal("99")));
            orderList.add(new OrderTestDTO(2,"aaa","02",new BigDecimal("20")));
            orderList.add(new OrderTestDTO(3,"bbb","01",new BigDecimal("17")));
            orderList.add(new OrderTestDTO(4,"ccc","02",new BigDecimal("19.88")));
    
            return orderList;
        }
    
        /**
         * 订单批量支付
         */
        public static void batchPay(List<OrderTestDTO> orderList){
            PayContext payContext = new PayContext();
            orderList.forEach( order -> {
                PayStrategy strategy = StrategySimpleFactory.initStrategy(order.getPayWay());
                payContext.setPayStrategy(strategy);
                payContext.executePayStrategy(order.getPayPersonName(), order.getPayMoney());
            });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    结果

    可以看到每笔订单都成功根据其支付方式支付了。
    在这里插入图片描述

    扩展一种支付方式:银行卡支付

    如果需要扩展一种支付方式,才能看出策略+工厂模式的真正优点。
    下面我们模拟扩展一种支付方式:银行卡支付

    支付策略新增

    package knowledege.designPattern.strategy.test1;
    
    import java.math.BigDecimal;
    
    public class CardStrategy implements PayStrategy{
    
        @Override
        public void pay(String name, BigDecimal money) {
            System.out.println("[" +name+ "]使用银行卡支付..." + money + "元");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    支付枚举新增

    PAY_CARD("03","银行卡"),
    
    • 1

    工厂新增生产银行卡

                case PAY_CARD:
                    strategy = new CardStrategy();
                    break;
    
    • 1
    • 2
    • 3

    重新测试

    在这里插入图片描述
    成功适配了银行卡支付,改动较少,又没有更改核心的支付逻辑,符合开闭原则!

  • 相关阅读:
    微擎模块 志汇同城微圈小程序10.9.5开源版
    MySQL的高级SQL语句
    Python 入门基础
    JAVA 版多商家入驻 直播带货 商城系统 B2B2C 商城免费搭建之 B2B2C产品概述
    Java安全之CC3
    什么是用户故事
    centos linux 和 centos stream 的区别
    windows ,C ,thread、
    oppo A57刷机包更新
    文件的随机读写函数:ftell & rewind
  • 原文地址:https://blog.csdn.net/shijizhe1/article/details/133933127