AI摘要
北海のAI

Java设计模式

一、Java设计模式

1、单例模式

2、策略模式

3、工厂模式

4、责任链模式

二、实际案例

1、多支付方式

现在需要设计一个可以支持阿里支付、微信支付、银联支付的支付接口该如何

  • 对于controller来说

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @RestController
    public class PayController {
    @Autowired
    PaymentStrategyFactory paymentStrategyFactory;

    @RequestMapping("/pay")
    public void pay(@RequestParam int payType,@RequestParam double amount) {
    paymentStrategyFactory.getPayment(PayEnum.fromValue(payType)).pay(amount);
    }

    }
  • 设计枚举类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public enum PayEnum {

    WXPAY(1), ALIPAY(2), UNIONPAY(3);

    private final int value;

    PayEnum(int value){
    this.value = value;
    }

    public int getValue() {
    return value;
    }

    public static PayEnum fromValue(int value) {
    for (PayEnum pay: PayEnum.values()) {
    if (pay.getValue() == value) {
    return pay;
    }
    }
    throw new IllegalArgumentException("Invalid value: " + value);
    }

    }
  • 设计策略接口

    1
    2
    3
    4
    5
    6
    public interface PaymentStrategy {

    void pay(double amount);
    PayEnum getHandleStrategy();

    }
  • 对于不同支付来说,去实现这个策略接口,然后注册为java的一个bean

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    /**
    * 阿里支付
    */
    @Service
    public class AliPay implements PaymentStrategy {

    @Override
    public void pay(double amount) {
    System.out.println("调用阿里进行支付~~~~~" + amount);
    }

    @Override
    public PayEnum getHandleStrategy() {
    return PayEnum.ALIPAY;
    }
    }

    /**
    * 银联支付
    */
    @Service
    public class UnionPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
    System.out.println("调用银联进行支付~~~~~" + amount);
    }

    @Override
    public PayEnum getHandleStrategy() {
    return PayEnum.UNIONPAY;
    }
    }

    /**
    * 微信支付
    */
    @Service
    public class WeChatPay implements PaymentStrategy {
    @Override
    public void pay(double amount) {
    System.out.println("调用微信进行支付~~~~~" + amount);
    }

    @Override
    public PayEnum getHandleStrategy() {
    return PayEnum.WXPAY;
    }
    }
  • 设计一个工厂类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Service
    public class PaymentStrategyFactory {

    public final ConcurrentHashMap<PayEnum, PaymentStrategy> handleStrategyMap = new ConcurrentHashMap<>();

    @Autowired
    public PaymentStrategyFactory(List<PaymentStrategy> iHandlers) {
    iHandlers.forEach(x -> handleStrategyMap.put(x.getHandleStrategy(), x));
    }

    public PaymentStrategy getPayment(PayEnum payEnum) {
    return handleStrategyMap.get(payEnum);
    }
    }

2、支付组合

对于上面多支付方式,如果来了一个需求需要不同支付方式进行组合使用

方案一:新增组合策略类

  • 创建组合策略接口

    1
    2
    3
    4
    5
    // 新增一个组合策略接口(可选)
    public interface CompositePaymentStrategy extends PaymentStrategy {
    void addPaymentStrategy(PaymentStrategy strategy);
    }

  • 实现组合策略类

    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
    @Service
    public class CompositePay implements CompositePaymentStrategy {

    private final List<PaymentStrategy> strategies = new ArrayList<>();

    @Override
    public void pay(double amount) {
    // 对每个支付策略执行支付逻辑
    for (PaymentStrategy strategy : strategies) {
    strategy.pay(amount);
    }
    }

    @Override
    public PayEnum getHandleStrategy() {
    // 组合策略没有具体的枚举值,返回 null 或自定义标识
    return null;
    }

    @Override
    public void addPaymentStrategy(PaymentStrategy strategy) {
    strategies.add(strategy);
    }
    }

  • 在控制器中使用组合策略

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RequestMapping("/compositePay")
    public void compositePay(@RequestParam List<Integer> payTypes, @RequestParam double amount) {
    CompositePay compositePay = new CompositePay();
    for (Integer payType : payTypes) {
    PaymentStrategy strategy = paymentStrategyFactory.getPayment(PayEnum.fromValue(payType));
    compositePay.addPaymentStrategy(strategy);
    }
    compositePay.pay(amount);
    }

方案二:责任链模式

  • 定义责任链解耦

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public abstract class PaymentHandler {
    protected PaymentHandler nextHandler;

    public void setNext(PaymentHandler handler) {
    this.nextHandler = handler;
    }

    public abstract void handle(double amount);
    }
  • 实现具体处理器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Component
    public class WeChatPayHandler extends PaymentHandler {
    @Override
    public void handle(double amount) {
    System.out.println("微信支付处理:" + amount);
    if (nextHandler != null) {
    nextHandler.handle(amount);
    }
    }
    }

    @Component
    public class AliPayHandler extends PaymentHandler {
    @Override
    public void handle(double amount) {
    System.out.println("支付宝处理:" + amount);
    if (nextHandler != null) {
    nextHandler.handle(amount);
    }
    }
    }

  • 构建责任链

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @Configuration
    public class PaymentChainConfig {

    @Autowired
    private WeChatPayHandler weChatPayHandler;

    @Autowired
    private AliPayHandler aliPayHandler;

    @Bean
    public PaymentHandler paymentChain() {
    weChatPayHandler.setNext(aliPayHandler);
    return weChatPayHandler;
    }
    }

  • 使用责任链

    1
    2
    3
    4
    5
    6
    7
    8
    @Autowired
    private PaymentHandler paymentChain;

    @RequestMapping("/chainPay")
    public void chainPay(@RequestParam double amount) {
    paymentChain.handle(amount);
    }