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

news2024/11/30 7:35:52

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控制,并使用策略模式执行具体的支付策略,通过设置不同的支付模板子类,我们可以选择不同的支付方式。

优点如下:

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

ps:以上内容,希望对大家有所帮助,如果有纰漏或有更好的想法,请您一定不要吝啬您的赐教。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/768720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[深度学习实战]基于PyTorch的深度学习实战(上)[变量、求导、损失函数、优化器]

目录 一、前言二、深度学习框架——PyTorch2.1 PyTorch介绍2.2 Python安装详解2.3 PyTorch安装详解 三、变量四、求导五、损失函数5.1 nn.L1Loss5.2 nn.SmoothL1Loss5.3 nn.MSELoss5.4 nn.BCELoss5.5 nn.CrossEntropyLoss5.6 nn.NLLLoss5.7 nn.NLLLoss2d 六、优化器Optim 6.1 …

ARM Coresight 系列文章 8 - ARM Coresight 通过 APBIC 级联使用

文章目录 APBIC 回顾APBIC 级联 上篇文章&#xff1a;ARM Coresight 系列文章 7 - ARM Coresight 通过 AHB-AP 访问 异构 cpu 内部 coresight 组件 APBIC 回顾 APBIC 可以连接一个或者多个APB BUS masters&#xff0c; 例如连接一个 APB-AP 组件和带有 APB 接口的 Processor&…

Java源码规则引擎:jvs-rules数据扩展及函数配置说明

jvs-rules数据拓展节点 数据拓展是数据可视化加工过程中的重要工具&#xff0c;它核心的作用是对原有数据表进行加工扩展&#xff0c;实现功能如下图所示 函数配置操作过程 操作说明 1、拖动数据拓展字段&#xff0c;并将字段拓展与之前的历史节点连接起来&#xff0c;点击数…

浅谈linux前台进程与后台进程同步异步执行的理解

最近书上看到前台进程以及后台进程的定义&#xff0c;有点令人费解。 linux终端输入一条命令&#xff0c;创建一个子进程运行这条命令&#xff0c;在这条命令进程执行完之前&#xff0c;终端shell都无法接收新的一条命令&#xff1b;只有这条命令运行结束后&#xff0c;当前终…

Vue项目实现在线预览pdf,并且可以批量打印pdf

最近遇到一个需求,就是要在页面上呈现pdf内容,并且还能用打印机批量打印pdf,最终效果如下: 当用户在列表页面,勾选中两条数据后,点击“打印表单”按钮之后,会跳到如下的预览页面: 预览页面顶部有个吸顶的效果,然后下方就展示出了2个pdf文件对应的内容,我们接着点击“…

Vsiual Stdio 生成动态链接库 / 命令行CMD工具打不开 / 64和32位动态链接库生成 dll

打开vistual studio&#xff0c;选择目标文件夹。 菜单栏选择工具->命令行->开发者命令提示 通过 这种方法打开的编译器版本是 32位&#xff08;x86&#xff09;的 64位的编译器通过以下方法打开 修改文件路径 1)Cd 路径 2) 盘符&#xff1a; 输入命令行代码 cl /c Se…

SpringBoot整合SpringSecurity+JWT

SpringBoot整合SpringSecurityJWT 整合SpringSecurity步骤 编写拦截链配置类&#xff0c;规定security参数拦截登录请求的参数&#xff0c;对该用户做身份认证。通过登录验证的予以授权&#xff0c;这里根据用户对应的角色作为授权标识。 整合JWT步骤 编写JWTUtils&#xf…

精智达在科创板上市:募资约11亿元,深创投等为其股东

7月18日&#xff0c;深圳精智达技术股份有限公司&#xff08;下称“精智达”&#xff0c;SH:688627&#xff09;在上海证券交易所科创板上市。本次上市&#xff0c;精智达的发行价为46.77元/股&#xff0c;发行数量为2350.2939万股&#xff0c;募资总额为10.99亿元&#xff0c;…

封装cpp-httplib成dll包,为老项目提供http网络支持

项目介绍&#xff1a; 公司内某些老的项目不支持https或者http1.1的一些新功能&#xff0c;需要开发对应的SDK供其调用&#xff0c;以便维护老项目。 第一步&#xff1a;下载cpp-httplib 点击这里去下载最新的代码&#xff1a;mirrors / yhirose / cpp-httplib GitCode 直接下…

QT:问题、解决与原因

在这里记录一些自己遇到的在QT开发上面的小问题和tips 目录 QComboBox 设置qss样式不生效qt按钮设置点击释放效果实现效果 QComboBox 设置qss样式不生效 我设置的样式是&#xff1a; box->setStyleSheet("QComboBox {""border: none;""padding:…

适用于 Type-C接口PD应用的智能二极管保护开关

日前&#xff0c;集设计、研发、生产和全球销售一体的著名功率半导体、芯片及数字电源产品供应商Alpha and Omega Semiconductor Limited&#xff08;AOS, 纳斯达克代码:AOSL) 推出一款采用理想二极管运作进行反向电流保护的新型Type-C PD 高压电源输入保护开关。AOZ13984DI-02…

上市公司前端开发规范参考

上市公司前端开发规范参考 命名规则通用约定文件与目录命名HTML命名CSS命名JS命名 代码格式通用约定HTML格式CSS格式JS格式注释 组件组件大小单文件组件容器组件组件使用说明Prop指令缩写组件通讯组件的挂载和销毁按需加载第三方组件库的规定 脚手架使用规范移动端脚手架PC端脚…

Linux下安装Elasticsearch以及ES-head插件

Linux下安装ElasticSearch以及ES-head插件 安装Elasticsearch 由于Elasticsearch客户端版本和ElasticSearch版本有对应关系&#xff0c;所以建议安装之前先考虑安装哪个版本的ElasticSearch。 ElasticSearch、Spring Data Elasticsearch、SpringBoot、Spring版本对应关系 安…

OpenCV for Python 学习第五天:图片属性的获取

上一篇博文当中&#xff0c;我们学习了如何获取图片的通道&#xff0c;我们了解了通道的分离方法split()和通道的组合方法merge()。那么我们今天就来对图片的属性做一个深入的了解。 文章目录 图片属性OpenCV中属性介绍图片属性的获取 图片属性 图片属性是指描述和定义一张图片…

爬虫与反爬虫的攻防对抗

一、爬虫的简介 1 概念 爬虫最早源于搜索引擎&#xff0c;它是一种按照一定的规则&#xff0c;自动从互联网上抓取信息的程序&#xff0c;又被称为爬虫&#xff0c;网络机器人等。按爬虫功能可以分为网络爬虫和接口爬虫&#xff0c;按授权情况可以分为合法爬虫和恶意爬虫。恶…

【NLP】从预训练模型中获取Embedding

从预训练模型中获取Embedding 背景说明下载IMDB数据集进行分词下载并预处理GloVe词嵌入数据构建模型训练模型并可视化结果结果对比其他代码 在NLP领域中&#xff0c;构建大规模的标注数据集非常困难&#xff0c;以至于仅用当前语料无法有效完成特定任务。可以采用迁移学习的方法…

hbuilder创建基于vue2的uniapp小程序项目

参考vant官网&#xff1a;https://vant-contrib.gitee.io/vant/v3/#/zh-CN/quickstart#an-zhuang官网 参考别人博客&#xff1a;https://www.yii666.com/blog/465379.html 1.创建项目 1.1 hbuilder进去右上角点击文件–新建–项目 1.2 vue2项目如下图 2.安装依赖 2.1 2.2…

Linux搭建SVN环境(最新版)

最新版本号(svn-1.14) https://opensource.wandisco.com/centos/7 更新版本库 sudo tee /etc/yum.repos.d/wandisco-svn.repo <<-EOF [WandiscoSVN] nameWandisco SVN Repo baseurlhttp://opensource.wandisco.com/centos/$releasever/svn-1.14/RPMS/$basearch/ enabled…

TypeScript 学习笔记(七):条件类型

条件类型 TS中的条件类型就是在类型中添加条件分支&#xff0c;以支持更加灵活的泛型&#xff0c;满足更多的使用场景。内置条件类型是TS内部封装好的一些类型处理&#xff0c;使用起来更加便利。 一、基本用法 当T类型可以赋值给U类型时&#xff0c;则返回X类型&#xff0c…

一探究竟:人工智能、机器学习、深度学习

一、人工智能 1.1 人工智能是什么&#xff1f; 1956年在美国Dartmounth 大学举办的一场研讨会中提出了人工智能这一概念。人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;简称AI&#xff0c;是计算机科学的一个分支&#xff0c;它企图了解智能的实质&am…