设计模式使用简例(简单工厂+策略模式+模板方法)

news2024/9/21 4:28:02

直接上代码,方便记忆。主要的要点,已经写到注释中。

一,代码展示

启动类

package com.rojer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

controller

package com.rojer.factoryMoudle.controller;

import com.rojer.factoryMoudle.PaymentStrategyFactory;
import com.rojer.factoryMoudle.impl.pay.AliPay;
import com.rojer.factoryMoudle.impl.pay.UnionPay;
import com.rojer.factoryMoudle.impl.pay.WechatPay;
import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import com.rojer.factoryMoudle.moudle.PayModule;
import com.rojer.factoryMoudle.impl.pay.inter.PaymentStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/")
public class PayController {

    @Autowired
    private PaymentStrategyFactory paymentStrategyFactory;

    /**
     * 普通写发法
     * @param module
     */
    @PostMapping("/online/pay1")
    public void pay(@RequestBody PayModule module) {
        PaymentStrategy paymentStrategy;
        switch (module.getPayType()) {
            case 1:
                paymentStrategy = new AliPay();
                break;
            case 2:
                paymentStrategy = new WechatPay();
                break;
            case 3:
                paymentStrategy = new UnionPay();
                break;
            default:
                throw new IllegalArgumentException("无效的支付类型");
        }
        paymentStrategy.pay(module.getPayAmount());
    }

    /**
     * 改造后写法
     * @param module
     */
    @PostMapping("/online/pay2")
    public void pay2(@RequestBody PayModule module) {
        AbstractPaymentStrategy strategy = paymentStrategyFactory.getPaymentStrategy(module.getPayType());
        strategy.commonPay(module.getPayAmount());
    }

}

策略接口

package com.rojer.factoryMoudle.impl.pay.inter;

import java.math.BigDecimal;

/**
 * 策略模式接口
 */
public interface PaymentStrategy {
    void pay(BigDecimal amount);
}

策略实现类

阿里支付类

package com.rojer.factoryMoudle.impl.pay;

import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 具体的策略实现AliPay
 */
@Component
public class AliPay extends AbstractPaymentStrategy {

    // 可注入别的类
    // @Autowired
    // private Pay pay;

    @Override
    public void pay(BigDecimal amount) {
        System.out.println("进行了阿里支付");
    }
}

银联支付类 

package com.rojer.factoryMoudle.impl.pay;

import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 具体的策略实现UnionPay
 */
@Component
public class UnionPay extends AbstractPaymentStrategy {

    // 可注入别的类
    // @Autowired
    // private Pay pay;

    @Override
    public void pay(BigDecimal amount) {
        System.out.println("进行了银联支付");
    }
}

微信支付类

package com.rojer.factoryMoudle.impl.pay;

import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * 具体的策略实现WechatPay
 */
@Component
public class WechatPay extends AbstractPaymentStrategy {

    // 可注入别的类
    // @Autowired
    // private Pay pay;

    @Override
    public void pay(BigDecimal amount) {
        System.out.println("进行了微信支付");
    }
}

简单工厂

package com.rojer.factoryMoudle;

import com.rojer.factoryMoudle.impl.pay.AliPay;
import com.rojer.factoryMoudle.impl.pay.UnionPay;
import com.rojer.factoryMoudle.impl.pay.WechatPay;
import com.rojer.factoryMoudle.impl.pay.abs.AbstractPaymentStrategy;
import com.rojer.factoryMoudle.moudle.PayEnum;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 设计模式之简单工厂
 */
@Component
public class PaymentStrategyFactory implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    /**
     * 使用简单工厂生成具体的支付对学校
     *
     * @param payType 支付类型
     * @return AbstractPaymentStrategy 抽象支付类
     */
    public AbstractPaymentStrategy getPaymentStrategy(Integer payType) {
        if (PayEnum.ALIPAY.getCode() == payType) {
            return applicationContext.getBean(AliPay.class);
        } else if (PayEnum.WECHATPAY.getCode() == payType){
            return applicationContext.getBean(WechatPay.class);
        } else if (PayEnum.UNIONPAY.getCode() == payType) {
            return applicationContext.getBean(UnionPay.class);
        } else {
            throw new IllegalArgumentException("无效的支付类型");
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

模板方法

package com.rojer.factoryMoudle.impl.pay.abs;

import com.rojer.factoryMoudle.impl.pay.inter.PaymentStrategy;

import java.math.BigDecimal;

/**
 * 设计模式之模板方法
 * 定义了支付的模板方法
 */
public abstract class AbstractPaymentStrategy implements PaymentStrategy {

    // 模板方法
    public final void commonPay(BigDecimal amount) {
        // 检测金额未合法数字
        check(amount);

        // 扩展支付
        pay(amount);

        // 可以继续扩展模板
    }

    // 声明未private,该方法不可被重写,必须按这个进行
    private void check(BigDecimal amount) {
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("无效的金额!");
        }
    }
}

module类

package com.rojer.factoryMoudle.moudle;

public enum PayEnum {
    ALIPAY(1, "Alipay"),
    WECHATPAY(2, "WeChat Pay"),
    UNIONPAY(3, "UnionPay");

    private final int code;
    private final String description;

    PayEnum(int code, String description) {
        this.code = code;
        this.description = description;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }

}
package com.rojer.factoryMoudle.moudle;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class PayModule {

    private Integer payType;

    private BigDecimal payAmount;
}

二,代码测试

正常值场合

错误值场合

文章学自徐庶老师抖音小课知识讲解。

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

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

相关文章

【电路笔记】-C类放大器

C类放大器 文章目录 C类放大器1、概述2、C类放大介绍3、C类放大器的功能4、C 类放大器的效率5、C类放大器的应用:倍频器6、总结1、概述 尽管存在差异,但我们在之前有关 A 类、B 类和 AB 类放大器的文章中已经看到,这三类放大器是线性或部分线性的,因为它们在放大过程中再现…

离线运行Llama3:本地部署终极指南_liama2 本地部署

4月18日&#xff0c;Meta在官方博客官宣了Llama3&#xff0c;标志着人工智能领域迈向了一个重要的飞跃。经过笔者的个人体验&#xff0c;Llama3 8B效果已经超越GPT-3.5&#xff0c;最为重要的是&#xff0c;Llama3是开源的&#xff0c;我们可以自己部署&#xff01; 本文和大家…

大话光学原理:3.干涉与衍射

一、干涉 这是一束孤独的光&#xff0c;在真空的无垠中悄无声息地穿行。忽然&#xff0c;一堵高耸的墙壁挡住了它的去路&#xff0c;它别无选择&#xff0c;只能硬着头皮冲撞而去。在摸索中&#xff0c;它意外地发现墙壁上竟有两道孔隙&#xff0c;笔直而细长&#xff0c;宛如量…

tableau树形图制作 - 7

树形图制作 1. 树状图绘制-11.1 选择属性1.2 智能选择树状图1.3 颜色设置 2. 树状图绘制-22.1 标签属性选择2.2 树状图绘制2.3 颜色设置2.4 设置标签2.5 设置筛选器 3. 树状图绘制 - 33.1 选择行列3.2 树状图转换3.3 统计转换3.4 颜色设置3.5 标签设置3.6 筛选器设置 1. 树状图…

【系统架构设计】计算机组成与体系结构(二)

计算机组成与体系结构 计算机系统组成存储器系统前言主存储器存储器存储数量&#xff08;计算&#xff09; 辅助存储器&#xff08;以磁盘为例&#xff09;Cache存储器 流水线 计算机系统组成 存储器系统 前言 存储器用来存放程序和数据的部件&#xff0c;是一个记忆装置&am…

Michael.W基于Foundry精读Openzeppelin第63期——Initializable.sol

Michael.W基于Foundry精读Openzeppelin第63期——Initializable.sol 0. 版本0.1 Initializable.sol 1. 目标合约2. 代码精读2.1 _getInitializedVersion() internal && _isInitializing() internal2.2 modifier initializer()2.3 modifier reinitializer(uint8 version…

Qt 异步实现事件的定时执行 - QTimer和QThread的联合使用

异步实现事件的定时执行 - QTimer和QThread的联合使用 引言一、核心源码二、其信号和槽函数简述三、定时器及其moveToThread简述 引言 在 Qt 中&#xff0c;如果想要定时执行某些事件或函数&#xff0c;通常会使用 QTimer 类。QTimer 允许设置一个时间间隔&#xff0c;当这个时…

聚星文社一键生成工具绘唐3科技AI工具

聚星文社一键生成工具绘唐3科技AI工具 绘唐3.0——用户文档 - 飞书云文档 聚星文社一键生成工具绘唐3科技AI工具是一个基于人工智能技术的辅助创作工具&#xff0c;可以帮助用户快速生成有关唐朝科技的文本内容。该工具利用自然语言处理和机器学习等技术&#xff0c;通过输入一…

opencv读取视频文件夹内视频的名字_时长_帧率_分辨率写入excel-cnblog

看视频的时候有的视频文件名贼长。想要翻看&#xff0c;在文件夹里根本显示不出来&#xff0c;缩短又会丢失一些信息&#xff0c;所以我写了一份Python代码&#xff0c;直接获取视频的名字&#xff0c;时长&#xff0c;帧率&#xff0c;还有分辨率写到excel里。 实际效果如下图…

Cesium自定义着色器构件三角面片【闪烁】问题,但是一移动视角就闪烁

问题&#xff1a;已知各个顶点的坐标信息、颜色和索引信息&#xff0c;并自定义绘制三角面片。 但是绘制的三角面片随着视角稍微改动就会出现闪烁现象&#xff01;&#xff01;&#xff01;why? Cesium数据类型的精度问题&#xff0c;例如下面为了获取能接收到高精度坐标信息…

linux磁盘分区管理

首先关机状态下&#xff0c;先配置硬盘 硬盘分区管理 识别硬盘 》分区规划 》 格式化 》 挂载使用 [rootlocalhost ~]# lsblk 查看硬盘 分区划分&#xff08;m帮助, p 查看分区, n 创建分区, d 删除分区, q 退出, w 保存&#xff0c; g gpt分区&#xff09; [roo…

华为云发起,openGemini正式成为CNCF官方项目!

openGemini 正式成为 CNCF 官方项目 北京时间2024年7月9日&#xff0c;云原生计算基金会&#xff08;CNCF&#xff09;正式接纳云原生高性能时序数据库项目 openGemini。openGemini的加入&#xff0c;极大地丰富了云原生数据库技术的探索、创新和发展。 openGemini是华为云数据…

打开excel时弹出stdole32.tlb

问题描述 打开excel时弹出stdole32.tlb 如下图&#xff1a; 解决方法 打开 Microsoft Excel 并收到关于 stdole32.tlb 的错误提示时&#xff0c;通常意味着与 Excel 相关的某个组件或类型库可能已损坏或不兼容。 stdole32.tlb 是一个用于存储自动化对象定义的类型库&#x…

BN的 作用

1、背景&#xff1a; 卷积神经网络的出现&#xff0c;网络参数量大大减低&#xff0c;使得几十层的深层网络成为可能。然而&#xff0c;在残差网络出现之前&#xff0c;网络的加深使得网络训练变得非常不稳定&#xff0c;甚至出现网络长时间不更新或者不收敛的情形&#xff0c;…

利用 Selenium 和 Python 实现网页新闻链接抓取

在网络数据分析和信息检索中&#xff0c;爬虫是一项非常重要的技术。爬虫可以自动化地从网页中提取信息&#xff0c;极大地提升数据收集的效率。本文将以一个具体的代码实例&#xff0c;讲解如何使用 Selenium 库进行网页新闻链接的抓取。 前期准备 在开始之前&#xff0c;需…

3-7 使用深度学习解决温度即示数问题

3-7 使用深度学习解决温度即示数问题 直接上代码 %matplotlib inline import matplotlib.pyplot as plt import numpy as np import torch torch.set_printoptions(edgeitems2, linewidth75)设置Jupyter Notebook在单元格中内嵌显示图像&#xff0c;导入所需库并设置PyTorch的…

实时温湿度监测系统:Micropython编码ESP32与DHT22模块的无线数据传输与PC端接收项目

实时温湿度监测系统 前言项目目的项目材料项目步骤模拟ESP32接线连接测试搭建PC端ESP32拷录环境对ESP32进行拷录PC端搭建桌面组件本地数据接收桌面小组件部分 实验总结 前言 人生苦短&#xff0c;我用Python。 由于我在日常工作中经常使用Python&#xff0c;因此在进行该项目…

物流工业三防平板实时跟踪货物位置和状态

在当今全球化和高度数字化的商业环境中&#xff0c;物流行业的高效运作对于企业的成功和经济的繁荣至关重要。货物的准确、实时跟踪不仅能提高物流效率&#xff0c;还能增强客户满意度&#xff0c;降低运营成本。物流工业三防平板的出现&#xff0c;为实现货物位置和状态的实时…

使用redis进行短信登录验证(验证码打印在控制台)

使用redis进行短信登录验证 一、流程1. 总体流程图2. 流程文字讲解&#xff1a;3.代码3.1 UserServiceImpl&#xff1a;&#xff08;难点&#xff09;3.2 拦截器LoginInterceptor&#xff1a;3.3 拦截器配置类&#xff1a; 4 功能实现&#xff0c;成功存入redis &#xff08;黑…

2017年,我成为了技术博主

2017年9月&#xff0c;我已经大三了。 >>上一篇&#xff08;爪哇&#xff0c;我初窥门径&#xff09; 我大二学了很多java技术&#xff0c;看似我一会就把javaweb/ssh/ssm这些技术栈给学了。 这些技术确实不难&#xff0c;即便是我&#xff0c;我都能学会&#xff0c;…