告别硬编码!用工厂模式优雅构建可扩展的 Spring Boot 应用 [特殊字符]

article/2025/6/19 22:06:42

嗨,各位技术伙伴们!👋

在日常的软件开发中,我们经常面临需求变更的挑战。如何构建一个既能满足当前需求,又能轻松应对未来变化的系统呢?答案往往藏在那些经典的设计模式中。

今天,我们就来聊聊创建型模式中的明星——工厂模式 (Factory Patterns),并深入探讨如何将其与强大的 Spring Boot 框架结合,打造出专业、灵活且易于维护的企业级应用。

什么是工厂模式?🤔

简单来说,工厂模式的核心思想就是将对象的创建过程封装起来,让客户端代码与具体对象的创建细节解耦。想象一下,你不再需要亲自去 new 一个复杂的对象,而是向一个“工厂”索要,工厂会根据你的需求生产出合适的对象。

工厂模式家族主要有三位成员:

  • 简单工厂 (Simple Factory):一个工厂类根据传入参数创建不同产品。简单直接,但不易扩展。
  • 工厂方法 (Factory Method):定义一个创建对象的接口,但由子类决定实例化哪个类。符合开闭原则,扩展性更好。
  • 抽象工厂 (Abstract Factory):用于创建一系列相关或相互依赖的对象(即一个产品族),而无需指定它们具体的类。

其中,工厂方法模式是应用非常广泛的一种。它的结构大致如下:

工厂模式在 Spring Boot 中的身影 💡

Spring 框架本身就是一个巨大的“工厂”的成功实践者!其核心的 IoC (控制反转) 容器就负责了我们应用中几乎所有对象 (Beans) 的创建、配置和管理。

在 Spring Boot 中,工厂模式的思想更是无处不在:

  1. @Bean 方法:在 @Configuration 类中,每一个被 @Bean 注解的方法都充当了一个工厂方法。Spring 调用这些方法来创建和管理 Bean 实例。

    @Configuration
    public class AppConfig {@Bean // 我就是一个工厂方法!public MyService myService(MyDependency dependency) {return new MyServiceImpl(dependency);}
    }
  2. FactoryBean 接口:Spring 提供的 FactoryBean 接口允许我们自定义更复杂的 Bean 创建逻辑。实现了该接口的类,其 getObject() 方法就是名副其实的工厂方法。

  3. 自动配置 (Auto-configuration):Spring Boot 的自动配置机制,在某种程度上也体现了抽象工厂的思想。它能根据不同的条件(如类路径、属性配置)为我们自动装配一整套协同工作的 Bean(一个“产品族”)。

实战演练:构建一个灵活的支付系统 💳

理论讲了不少,让我们通过一个实战项目来感受工厂模式的魅力。我们将构建一个支持多种支付方式(如支付宝、微信支付、银行卡支付)的系统。

核心思路

  1. 定义一个统一的 PaymentService 支付接口。
  2. 为每种支付方式创建具体的实现类 (如 AlipayServiceImpl),并将它们注册为 Spring 的 @Service Bean。
  3. 创建一个 PaymentServiceFactoryImpl,它利用 Spring 的依赖注入特性,自动收集所有 PaymentService 的实现。
  4. 提供一个方法,根据传入的支付类型,从工厂中获取相应的服务实例。
  5. 通过一个 PaymentController 暴露 API,接收支付请求并调用工厂进行处理。

下面是我们支付系统核心组件的简化结构图:

关键代码片段(示意):

  • PaymentService 接口:

    public interface PaymentService {void pay(BigDecimal amount);PaymentType getServiceType(); // 用于工厂识别
    }
  • AlipayServiceImpl (具体服务):

    @Service("alipayService")
    public class AlipayServiceImpl implements PaymentService {// ... 实现 pay() 和 getServiceType()
    }
  • PaymentServiceFactoryImpl (核心工厂):

    @Component
    public class PaymentServiceFactoryImpl {private final Map<PaymentType, PaymentService> serviceCache;@Autowired // 注入所有PaymentService实现public PaymentServiceFactoryImpl(List<PaymentService> services) {// ... 初始化serviceCache}public PaymentService getPaymentService(PaymentType type) {// ... 从cache中获取}
    }

这种设计的最大好处是什么? 可扩展性! 当我们需要支持一种新的支付方式(比如 Apple Pay)时,只需要:

  1. 在 PaymentType 枚举中添加新类型。
  2. 创建一个 ApplePayServiceImpl 实现 PaymentService接口,并标记为 @Service
  3. 完成! 工厂会自动发现并注册这个新服务,无需修改工厂或控制器的代码,完美符合开闭原则

核心优势与总结 🌟

通过本次学习和实践,我们可以看到工厂模式(特别是结合 Spring Boot 特性)能为我们带来:

  • 高度解耦:客户端与具体产品实现分离。
  • 增强灵活性:轻松切换和新增产品实现。
  • 提高可维护性:代码结构更清晰,职责更分明。
  • 遵循开闭原则:对扩展开放,对修改关闭。

设计模式并非银弹,但它们是前人智慧的结晶,能帮助我们写出更优雅、更健壮的代码。

动手实践,一探究竟!🚀

理论与实践相结合才能真正掌握。我已经将本次学习和实践的完整代码(包括基础的工厂模式示例和 Spring Boot 支付系统项目)上传到了 GitHub,欢迎大家克隆、学习和交流!

代码仓库地址: https://github.com/Wilsoncyf/design-pattern-springboot.git


学习设计模式是一个持续精进的过程。您在项目中常用的设计模式有哪些呢?欢迎在评论区留言,一起交流探讨,共同进步!💪


http://www.hkcw.cn/article/xbBYxWchoi.shtml

相关文章

azure web app创建分步指南系列之二

为注册表授权托管标识 你创建的托管标识尚未获得从容器注册表中提取数据的授权。在此步骤中,你将启用授权。 返回容器注册表的管理页面: 在左侧导航菜单中,选择“访问控制 (IAM)”。选择“添加角色分配”。此屏幕截图显示了如何为容器注册表启用添加角色分配。在角色列表中…

使用Yolov8 训练交通标志数据集:TT100K数据集划分

使用Yolov8 训练交通标志数据集&#xff1a;TT100K数据集划分&#xff08;一&#xff09; 一、数据集下载二、划分数据集三、目录放置 一、数据集下载 官方网址&#xff1a;TT100K 数据集对比 源码如下&#xff1a; def classes(filedir):with open(filedir) as f:classes …

【PostgreSQL 03】PostGIS空间数据深度实战:从地图服务到智慧城市

PostGIS空间数据深度实战&#xff1a;从地图服务到智慧城市 关键词 PostGIS, 空间数据库, 地理信息系统, GIS, 空间查询, 地理分析, 位置服务, 智慧城市, 空间索引, 坐标系统 摘要 PostGIS是PostgreSQL的空间数据扩展&#xff0c;它将普通的关系数据库转变为强大的地理信息系统…

Wireshark 使用教程:让抓包不再神秘

一、什么是 tshark&#xff1f; tshark 是 Wireshark 的命令行版本&#xff0c;支持几乎所有 Wireshark 的核心功能。它可以用来&#xff1a; 抓包并保存为 pcap 文件 实时显示数据包信息 提取指定字段进行分析 配合 shell 脚本完成自动化任务 二、安装与验证 Kali Linux…

环境变量Path单行显示改回多行列表显示

环境变量Path单行显示改回多行列表显示 今天去配置环境变量时&#xff0c;双击Path竟然只显示一行&#xff0c;明明记得上次还时一个列表显示来着。由于以前有删除了所有Path变量的经历&#xff0c;所以看到这个情况属实吓我一跳且一脸懵。 仔细地看了一下&#xff0c;Path中…

CodeTop100 Day18

52、最长的有效括号 括号问题需要考虑栈&#xff0c;而最长有效的括号就要考虑动态规划了 这里定义dp[i]为以i-1位置结尾的最长合法括号字串 遍历字符串&#xff0c;当遇到左括号&#xff0c;压入栈&#xff0c;dp[i1]0,遇到右括号&#xff0c;如果栈不为空&#xff0c;配对左…

NLP基础:从词嵌入到预训练模型应用

NLP基础&#xff1a;从词嵌入到预训练模型应用 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 NLP基础&#xff1a;从词嵌入到预训练模型应用摘要引言一、词嵌入技术&#xff1a;从离散到连续的语义表示1. 传统词嵌…

STM32CubeMX串口配置

STM32CubeMX串口配置 一&#xff0c;Mode1&#xff0c;Asynchronous&#xff08;异步模式&#xff09;2&#xff0c;其他模式3&#xff0c;异步通信中的流控 二&#xff0c;Configuration参数配置(Parameter Settings)1&#xff0c;Basic Parameters2&#xff0c;Advanced Para…

Java内存模型(JMM)与多线程编程实战

最近正在复习Java八股&#xff0c;所以会将一些热门的八股问题&#xff0c;结合ai与自身理解写成博客便于记忆 今天将以这四个问题为依据。 一、JMM内存模型解析 1. JMM核心概念 Java内存模型(Java Memory Model)定义了Java程序中各种变量&#xff08;线程共享变量&#xf…

Spring Cache核心原理与快速入门指南

文章目录 前言一、Spring Cache核心原理1.1 架构设计思想1.2 运行时执行流程1.3 核心组件协作1.4 关键机制详解1.5 扩展点设计1.6 与Spring事务的协同 二、快速入门实战三、局限性3.1 多级缓存一致性缺陷3.2 分布式锁能力缺失3.3 事务集成陷阱 总结 前言 在当今高并发、低延迟…

【设计模式-4.5】行为型——迭代器模式

说明&#xff1a;本文介绍设计模式中&#xff0c;行为型设计模式之一的迭代器模式。 定义 迭代器模式&#xff08;Iterator Pattern&#xff09;&#xff0c;也叫作游标模式&#xff08;Cursor Pattern&#xff09;&#xff0c;它提供一种按顺序访问集合/容器对象元素的方法&…

【Python训练营打卡】day40 @浙大疏锦行

DAY 40 训练和测试的规范写法 知识点回顾&#xff1a; 1. 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中 2. 展平操作&#xff1a;除第一个维度batchsize外全部展平 3. dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropo…

软件技术如何赚钱

1. 开发并销售软件产品​ ​ 独立应用开发&#xff1a;针对特定需求或市场痛点&#xff0c;开发移动应用、桌面软件或网页应用。例如&#xff0c;开发一款专注于时间管理的移动应用&#xff0c;帮助用户提高工作效率。以 Python 结合 Kivy 框架开发一个简单的待办事项应用为例…

【Github/Gitee Webhook触发自动部署-Jenkins】

Github/Gitee Webhook触发自动部署-Jenkins #mermaid-svg-ryhZQMOzmkQZNMwX {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ryhZQMOzmkQZNMwX .error-icon{fill:#552222;}#mermaid-svg-ryhZQMOzmkQZNMwX .error-tex…

华为OD机试真题——最小的调整次数/特异性双端队列(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《最小的调整次数/特异性双端…

建筑兔零基础人工智能自学记录101|Transformer(1)-14

Transformer 谷歌提出&#xff0c;一组编码-解码器 可以同时处理&#xff0c;通过位置编码来处理单词 实质是token词语接龙&#xff08;只是有不同的概率&#xff09; token对应向量 Transformer简述 文生图就需要用到transformer黑箱 token 内部层次 中间主要是embedding…

网线水晶头接法与8根线芯作用解析

网线的正确接法至关重要&#xff0c;它直接影响网络的稳定性与传输速度。而了解每根线的作用&#xff0c;更是深入掌握网络布线知识的关键。常见的网线为非屏蔽双绞线&#xff08;UTP&#xff09;&#xff0c;内部包含 8 根不同颜色的线芯&#xff0c;两两相互缠绕&#xff0c;…

【GESP真题解析】第 2 集 GESP 三级样题卷编程题 1:逛商场

大家好,我是莫小特。 这篇文章给大家分享 GESP 三级样题卷编程题第 1 题:逛商场。 题目链接 洛谷链接:B3848 逛商场 一、完成输入 根据输入格式描述,输入一共有三行,第一行为整数 N,数据范围: 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100,使用 int 类型。 第二行为 N …

Nacos实战——动态 IP 黑名单过滤

1、需求分析 一些恶意用户&#xff08;‏可能是黑客、爬虫、DDoS ؜攻击者&#xff09;可能频繁请求服务器资​源&#xff0c;导致资源占用过高。针对这种问题&#xff0c;可以通过IP‏ 封禁&#xff0c;可以有效拉؜黑攻击者&#xff0c;防止资源​被滥用&#xff0c;保障合法…

基于Web的濒危野生动物保护信息管理系统设计(源码+定制+开发)濒危野生动物监测与保护平台开发 面向公众参与的野生动物保护与预警信息系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…