设计模式结合场景(1)——支付场景(策略+工厂+模板)

ps:以下示例仅供参考,设计模式只是一种思想,至于怎么千变万化就看大家了。

一、背景

面试官:你们项目的支付场景用了哪些设计模式,为什么要这么做?

二、方案

  • 使用策略模式定义不同支付方式的具体支付策略,每种支付方式对应一个策略类。
  • 使用工厂模式创建支付对象,将具体的逻辑封装在工厂类中,工厂类根据不同的支付方式创建相应的支付对象。
  • 使用模板模式定义支付流程的通用框架,将整个支付流程抽象成一个模板方法,定义一系列步骤,然后具体的支付方式实现这个模板方法,并完成各自特定的支付逻辑。

三、UML类图

四、代码实现

4.1 Payment——支付接口

定义支付的基本行为。(ps:需要入参加上入参即可)

/**
 * @author Created by njy on 2023/7/16
 * 支付接口
 */
public interface Payment {
    //校验参数
    void validatePayment();
    //发起请求
    void executePayment();
    //处理结果
    void processPaymentResult();

    String getType();
}

4.2 Alipay、WeChatPay——支付具体策略

/**
 * @author Created by njy on 2023/7/16
 * 支付宝支付
 */
@Component
public class Alipay implements Payment {
    @Override
    public void validatePayment() {
        // 验证支付宝支付参数
        System.out.println("验证支付宝支付请求参数。。。");
    }
    @Override
    public void executePayment() {
        // 发送支付宝支付请求
        System.out.println("发起支付宝支付请求。。。。");
    }
    @Override
    public void processPaymentResult() {
        // 处理支付宝支付结果
        System.out.println("正在处理支付结果。。。");
    }
    @Override
    public String getType() {
        return "Alipay";
    }
}
/**
 * @author Created by njy on 2023/7/16
 * 微信支付
 */
@Component
public class WechatPay implements Payment{
    @Override
    public void validatePayment() {
        // 验证支付宝支付参数
        System.out.println("验证微信支付请求参数。。。");
    }
    @Override
    public void executePayment() {
        // 发送支付宝支付请求
        System.out.println("发起微信支付请求。。。。");
    }
    @Override
    public void processPaymentResult() {
        // 处理支付宝支付结果
        System.out.println("正在处理支付结果。。。");
    }
    @Override
    public String getType() {
        return "WeChatPay";
    }
}

4.3 PaymentFactory——支付工厂

创建具体的支付对象。

/**
 * @author Created by njy on 2023/7/16
 * 支付工厂
 */
@Component
public class PaymentFactory {
    private List<Payment> payments;
    private static final Map<String, Payment> paymentMap = new ConcurrentHashMap<>();
    //项目启动时把支付类型和对应的payment放入map中
    @PostConstruct
    protected void init() {
        if (payments != null) {
            payments.forEach(payment -> paymentMap.put(payment.getType(), payment));
        }
    }
    public Payment select(String payType) {
        Payment payment = paymentMap.get(payType);
        if (null == payment) {
            throw new IllegalArgumentException("Invalid payment method");
        }
        return payment;
    }
    @Autowired
    public void setpayments(List<Payment> payments) {
        this.payments = payments;
    }
}

4.4 PaymentTemplate——抽象模板

定义了支付流程的通用框架。

/**
 * @author Created by njy on 2023/7/17
 * 支付模板
 */
public abstract class PaymentTemplate {

    //模板方法
    public void processPayment() {
        Payment payment = selectPay();
        //验证参数
        payment.validatePayment();
        //发起请求
        payment.executePayment();
        //结果处理
        payment.processPaymentResult();
        if (isReceipt()) {
            System.out.println(payment.getType()+"支付,开具小票。。。。");
        }else {
            System.out.println(payment.getType()+"支付,不开小票");
        }
        //do something:支付后的操作,例如成功或失败后的回调
    }
    //抽象方法
    public abstract Payment selectPay();
    //钩子方法:是否开具小票
    public boolean isReceipt(){
        return false;
    }
}

4.5 WeChat、AlipayTemplate——具体模板

/**
 * @author Created by njy on 2023/7/17
 * 微信支付模板
 */
@Component
public class WeChatTemplate extends PaymentTemplate{
    @Autowired
    private PaymentFactory factory;
    @Override
    public Payment selectPay() {
        return factory.select("WeChatPay");
    }
    @Override
    public boolean isReceipt() {
        return true;
    }
}
/**
 * @author Created by njy on 2023/7/17
 * 支付宝支付模板
 */
@Component
public class AliTemplate extends PaymentTemplate{
    @Resource
    private PaymentFactory factory;
    @Override
    public Payment selectPay() {
        return factory.select("Alipay");
    }
}

4.6 test

/**
 * @author Created by njy on 2023/7/18
 * 策略+工厂+模板模式测试
 */
@SpringBootTest
public class Factory_strategt_template {
    @Autowired
    AliTemplate aliTemplate;
    @Autowired
    WeChatTemplate weChatTemplate;
    @Test
    public void test(){
        //支付宝
        System.out.println("-------支付宝支付-----------");
        aliTemplate.processPayment();
        System.out.println("---------微信支付----------");
        weChatTemplate.processPayment();
    }
}

五、总结

对上述例子做个总结:

        Payment和具体的支付类,通过工厂类PaymentFactory创建具体的支付对象,而支付流程则由支付模板类PaymentTemplate控制,并使用策略模式执行具体的支付策略,通过设置不同的支付模板子类,我们可以选择不同的支付方式。

优点如下:

  • 支付方式的扩展性:如果以后添加了一种支付方式,那么只需要创建对应的策略类即可,无需修改原有的代码,符合开闭原则。
  • 支付流程的通用性:通过模板方法模式,把支付流程的通用步骤抽象成模板方法,确保了一致性的支付流程。
  • 灵活且可配置:通过工厂模式创建支付对象,并使用策略模式管理不同的支付方式,可以根据配置或上下文的需要动态选择支付方式。

END:更多设计模式的介绍,推荐移步至👉 23种设计模式学习导航(Java完整版)👈

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橡 皮 人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值