策略模式+工厂模式实现多模式支付系统

在现代软件架构中,策略模式和工厂模式是两种非常实用的设计模式,它们可以提高代码的灵活性和可维护性。本文将结合这两种模式,介绍如何实现一个支持多种支付方式的支付系统。

一、背景介绍

在电子商务平台中,支付功能是核心功能之一。随着业务的发展,平台可能需要支持多种支付方式,如支付宝、微信支付、京东支付等。每种支付方式都有其特定的API和业务逻辑。为了应对这种多样化的需求,我们需要一个灵活且可扩展的支付系统设计。

二、策略模式

策略模式定义了一系列算法,将每个算法封装起来,让它们可以互换。这样,算法可以独立于使用它的客户端变化。

1. 定义支付策略接口

首先,我们定义一个支付策略接口,包含统一下单、退款、查询支付状态和关闭订单的方法。

package net.xdclass.component;

import net.xdclass.vo.PayInfoVO;

public interface PayStrategy {
    String unifiedOrder(PayInfoVO payInfoVO);
    String refund(PayInfoVO payInfoVO);
    String queryPayStatus(PayInfoVO payInfoVO);
    String closeOrder(PayInfoVO payInfoVO);
}

2. 实现具体策略

然后,为每种支付方式实现具体的支付策略。

package net.xdclass.component;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.vo.PayInfoVO;
import org.springframework.stereotype.Service;


@Service
@Slf4j
public class AliPayStrategy implements PayStrategy {

    @Override
    public String unifiedOrder(PayInfoVO payInfoVO) {
        // 支付宝统一下单逻辑
        return "支付宝下单成功";
    }

    @Override
    public String refund(PayInfoVO payInfoVO) {
        // 支付宝退款逻辑
        return "支付宝退款成功";
    }

    @Override
    public String queryPayStatus(PayInfoVO payInfoVO) {
        // 支付宝查询订单状态逻辑
        return "支付宝订单成功";
    }

    @Override
    public String closeOrder(PayInfoVO payInfoVO) {
        // 支付宝关闭订单逻辑
        return "支付宝订单关闭成功";
    }
}

package net.xdclass.component;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.vo.PayInfoVO;
import org.springframework.stereotype.Service;


@Service
@Slf4j
public class WechatPayStrategy implements PayStrategy {

    @Override
    public String unifiedOrder(PayInfoVO payInfoVO) {
        // 微信统一下单逻辑
        return "微信支付下单成功";
    }

    @Override
    public String refund(PayInfoVO payInfoVO) {
        // 微信退款逻辑
        return "微信退款成功";
    }

    @Override
    public String queryPayStatus(PayInfoVO payInfoVO) {
        // 微信查询订单状态逻辑
        return "微信订单成功";
    }

    @Override
    public String closeOrder(PayInfoVO payInfoVO) {
        // 微信关闭订单逻辑
        return "微信订单关闭成功";
    }
}

3. 支付策略上下文

为了更好地管理支付策略,我们可以使用Spring的@Service注解将策略类注册为Spring Bean。

package net.xdclass.component;

import net.xdclass.vo.PayInfoVO;

public class PayStrategyContext {
    private PayStrategy payStrategy;

    public PayStrategyContext(PayStrategy payStrategy) {
        this.payStrategy = payStrategy;
    }

    public String executeUnifiedOrder(PayInfoVO payInfoVO) {
        return payStrategy.unifiedOrder(payInfoVO);
    }

    public String executeRefund(PayInfoVO payInfoVO) {
        return payStrategy.refund(payInfoVO);
    }

    public String executeCloseOrder(PayInfoVO payInfoVO) {
        return payStrategy.closeOrder(payInfoVO);
    }

    public String executeQueryPayStatus(PayInfoVO payInfoVO) {
        return payStrategy.queryPayStatus(payInfoVO);
    }
}

三、工厂模式

工厂模式用于创建对象,而无需指定将要创建的对象的具体类。这样,客户端代码就可以与具体类解耦。

1. 定义支付工厂

定义一个支付工厂,根据支付类型创建对应的支付策略对象。

package net.xdclass.component;

import lombok.extern.slf4j.Slf4j;
import net.xdclass.enums.ProductOrderPayTypeEnum;
import net.xdclass.vo.PayInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class PayFactory {

    @Autowired
    private AliPayStrategy aliPayStrategy;

    @Autowired
    private WechatPayStrategy wechatPayStrategy;

    /**
     * 创建支付,简单工厂模式
     * @param payInfoVO
     * @return
     */
    public String pay(PayInfoVO payInfoVO) {
        String payType = payInfoVO.getPayType();

        if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {
            // 支付宝支付
            PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);
            return payStrategyContext.executeUnifiedOrder(payInfoVO);
        } else if (ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)) {
            // 微信支付
            PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);
            return payStrategyContext.executeUnifiedOrder(payInfoVO);
        }
        return "";
    }

    /**
     * 关闭订单
     * @param payInfoVO
     * @return
     */
    public String closeOrder(PayInfoVO payInfoVO) {
        String payType = payInfoVO.getPayType();

        if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {
            // 支付宝支付
            PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);
            return payStrategyContext.executeCloseOrder(payInfoVO);
        } else if (ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)) {
            // 微信支付
            PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);
            return payStrategyContext.executeCloseOrder(payInfoVO);
        }
        return "";
    }

    /**
     * 查询支付状态
     * @param payInfoVO
     * @return
     */
    public String queryPayStatus(PayInfoVO payInfoVO) {
        String payType = payInfoVO.getPayType();

        if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {
            // 支付宝支付
            PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);
            return payStrategyContext.executeQueryPayStatus(payInfoVO);
        } else if (ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)) {
            // 微信查询支付状态
            PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);
            return payStrategyContext.executeQueryPayStatus(payInfoVO);
        }
        return "";
    }

    /**
     * 退款接口
     * @param payInfoVO
     * @return
     */
    public String refund(PayInfoVO payInfoVO) {
        String payType = payInfoVO.getPayType();

        if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {
            // 支付宝支付
            PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);
            return payStrategyContext.executeRefund(payInfoVO);
        } else if (ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)) {
            // 微信退款
            PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);
            return payStrategyContext.executeRefund(payInfoVO);
        }
        return "";
    }
}
2. 支付上下文

支付上下文负责执行具体的支付操作,它持有一个支付策略对象,并调用其方法执行支付操作。

package net.xdclass.component;

import net.xdclass.vo.PayInfoVO;



public class PayStrategyContext {
    private PayStrategy payStrategy;

    public PayStrategyContext(PayStrategy payStrategy){
        this.payStrategy = payStrategy;
    }

    /**
     * 根据策略对象,执行不同的下单接口
     * @return
     */
    public String executeUnifiedOrder(PayInfoVO payInfoVO){
        return payStrategy.unifiedOrder(payInfoVO);
    }

    /**
     * 根据策略对象,执行不同的退款接口
     * @return
     */
    public String executeRefund(PayInfoVO payInfoVO){
        return payStrategy.refund(payInfoVO);
    }

    /**
     * 根据策略对象,执行不同的关闭接口
     * @return
     */
    public String executeCloseOrder(PayInfoVO payInfoVO){
        return payStrategy.closeOrder(payInfoVO);
    }

    /**
     * 根据策略对象,执行不同的查询订单状态接口
     * @return
     */
    public String executeQueryPayStatus(PayInfoVO payInfoVO){
        return payStrategy.queryPayStatus(payInfoVO);
    }
}

四、整合与测试

将上述组件整合到一起,并通过单元测试验证其功能。

1. 整合

在Spring Boot应用中,通过@Autowired自动装配上述组件。

2. 测试

编写单元测试,验证支付功能的正确性。

package net.xdclass.component;

import net.xdclass.vo.PayInfoVO;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;

public class PayFactoryTest {

    @Test
    public void testPay() {
        PayInfoVO payInfoVO = new PayInfoVO();
        payInfoVO.setPayType("ALI_PAY");
        payInfoVO.setOutTradeNo("123456");
        payInfoVO.setPayFee(100L);
        payInfoVO.setOrderPayTimeoutMills(30000L);

        PayFactory payFactory = new PayFactory();
        String result = payFactory.pay(payInfoVO);
        System.out.println(result);
    }

    @Test
    public void testCloseOrder() {
        PayInfoVO payInfoVO = new PayInfoVO();
        payInfoVO.setPayType("ALI_PAY");
        payInfoVO.setOutTradeNo("123456");
        payInfoVO.setPayFee(100L);
        payInfoVO.setOrderPayTimeoutMills(30000L);

        PayFactory payFactory = new PayFactory();
        String result = payFactory.closeOrder(payInfoVO);
        System.out.println(result);
    }
}

五、总结

通过策略模式和工厂模式的结合,我们实现了一个灵活且可扩展的支付系统。每种支付方式都实现了一个具体的支付策略,而支付工厂负责根据支付类型创建相应的支付策略对象。这种设计不仅简化了客户端代码,还提高了系统的可维护性和可扩展性。

这种设计模式的结合使得在添加新的支付方式时,只需实现一个新的支付策略类并注册到支付工厂中,无需修改现有代码。同时,策略模式的使用也使得每种支付方式的业务逻辑独立,便于管理和维护。

在未来的发展中,可以进一步扩展支持更多的支付方式,如银联支付、PayPal等,只需增加相应的策略类即可。此外,还可以考虑引入配置中心,动态配置支付方式,以适应不断变化的业务需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值