基于订单批量支付场景,对策略模式和简单工厂模式进行简单实现
文章目录
- 策略模式
- 介绍
- 实现
- 抽象策略
- 具体策略
- 1.AliPayStrategy
- 2.WeChatPayStrategy
 
- 环境
 
 
- 使用简单工厂来获取具体策略对象
- 支付方式枚举
- 策略工厂接口
- 策略工厂实现
 
- 测试使用
- 订单实体类
- 对订单进行批量支付
- 结果
 
- 扩展一种支付方式:银行卡支付
- 支付策略新增
- 支付枚举新增
- 工厂新增生产银行卡
- 重新测试
 
策略模式
介绍
以下是菜鸟教程对策略模式的介绍: 策略模式
在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。
策略模式主要有三个角色:
- 抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
- 具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。
- 环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。
实现
抽象策略
我们使用接口来实现抽象策略,规定了支付的公共方法,根据传入的用户名和支付金额进行结算。
package knowledege.designPattern.strategy.test1;
import java.math.BigDecimal;
public interface PayStrategy {
    void pay(String name, BigDecimal money);
}
具体策略
初始化微信和支付宝两种支付策略
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 + "元");
    }
}
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 + "元");
    }
}
环境
提供设置策略和执行策略的方法
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);
    }
}
使用简单工厂来获取具体策略对象
支付方式枚举
定义枚举并支持静态根据支付方式获取枚举
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;
    }
}
策略工厂接口
public interface StrategyFactory {
    PayStrategy initStrategy();
}
策略工厂实现
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;
    }
}
测试使用
订单实体类
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;
}
对订单进行批量支付
模拟对订单进行批量支付
- 模拟获取一批订单
- 循环订单进行支付 
  - 根据订单的支付方式,获取支付枚举
- 根据枚举,使用工厂模式获取支付策略
- 根据策略,使用支付环境进行支付
 
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());
        });
    }
}
结果
可以看到每笔订单都成功根据其支付方式支付了。
 
扩展一种支付方式:银行卡支付
如果需要扩展一种支付方式,才能看出策略+工厂模式的真正优点。
 下面我们模拟扩展一种支付方式:银行卡支付
支付策略新增
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 + "元");
    }
}
支付枚举新增
PAY_CARD("03","银行卡"),
工厂新增生产银行卡
            case PAY_CARD:
                strategy = new CardStrategy();
                break;
重新测试

 成功适配了银行卡支付,改动较少,又没有更改核心的支付逻辑,符合开闭原则!




![web:[MRCTF2020]Ez_bypass](https://img-blog.csdnimg.cn/273e0513502d46728fd26a73f679d02e.png)














