当前位置: 首页 > article >正文

抽象工厂设计模式及应用案例

引言

在软件开发中,合理的设计模式可以有效地提高代码的可维护性、可扩展性和可重用性。抽象工厂模式(Abstract Factory Pattern)便是一个重要的创建型设计模式,它允许我们在不指定具体类的情况下,创建一系列相关或相互依赖的对象。本文将探讨抽象工厂模式的基本概念、优点,并通过 Spring 框架中的具体案例,说明其实际应用。

抽象工厂模式概述

定义

抽象工厂模式提供一个创建对象的接口,但允许子类决定具体要实例化的类。它的主要目的是通过工厂方法隔离具体的类,从而使得系统在扩展时能够更容易地替换组件。

结构

  1. 抽象工厂:定义一个创建产品的接口。
  2. 具体工厂:实现抽象工厂接口,负责创建具体的产品对象。
  3. 抽象产品:定义产品的接口。
  4. 具体产品:实现抽象产品接口的具体对象。

UML 类图

          AbstractFactory/        |        \ProductA1  ProductB1  ProductA2|           |          |ConcreteA1  ConcreteB1  ConcreteA2

抽象工厂模式的优点

  1. 解耦合:客户端不需要了解具体类的实现,降低了系统的耦合度。
  2. 扩展性强:增加新产品时,只需添加新的工厂和产品类,不影响现有代码。
  3. 一致性:确保创建的产品系列之间的一致性,使得使用者可以很方便地切换产品系列。
  4. 灵活性:通过工厂方法,客户端可以选择创建的具体对象,而无需更改其他代码。

Spring 全家桶中的抽象工厂模式应用

在 Spring 框架中,许多概念和设计模式与抽象工厂模式相结合,极大地增强了 Spring 的灵活性和可扩展性。以下是几个具体的案例。

1. CDATA和由 Spring 容器提供的 BeanFactory

场景:在构建一个大型应用时,可能需要不同类型的 Bean,比如数据源、服务、控制器等。

实现

Spring容器通过 BeanFactoryApplicationContext 接口为不同的 Bean 提供创建和管理的功能,而这些容器可以被看作是一个抽象工厂的实现。

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class SpringExample {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);MyService myService = context.getBean(MyService.class);myService.performService();}
}

在这个例子中,ApplicationContext 就是一个抽象工厂,负责创建和管理 MyService 这个 Bean。

2. 使用 @Configuration 和 @Bean 注解

场景:假设我们创建一个不同的支付服务,需要根据不同的环境(如开发、测试和生产)使用不同的实现。

实现

通过配置类和注解,我们可以采用类似工厂的方式创建不同的 Bean。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class PaymentConfig {@Beanpublic PaymentService paymentService() {// 根据环境选择不同的支付实现return new PayPalPaymentService(); // 或使用 StripePaymentService}
}

3. Spring Profiles的灵活性

场景:在开发和生产环境中,我们需要使用不同的数据源(如 H2 和 MySQL)。

实现

可以使用 Spring Profiles 功能来动态选择使用的 Bean,类似于抽象工厂的多种实现。

@Configuration
@Profile("dev")
public class DevDataSourceConfig {@Beanpublic DataSource dataSource() {return new H2DataSource();}
}@Configuration
@Profile("prod")
public class ProdDataSourceConfig {@Beanpublic DataSource dataSource() {return new MySQLDataSource();}
}

在运行时,Spring 会根据激活的 Profile 动态选择 DataSource 的具体实现。这种方式体现了抽象工厂模式的灵活性和可扩展性。

总结

抽象工厂模式在软件设计中起着至关重要的作用,能够有效地解耦组件,增加系统的灵活性与可扩展性。Spring 全家桶充分利用了这一设计模式,通过容器和注解机制为开发者提供了一种便捷的方式来管理和使用不同的对象,实现了高内聚和低耦合的设计原则。随着应用的复杂性增加,合理应用抽象工厂模式将使我们的代码更具可维护性和可扩展性,提升开发效率。

相关文章:

抽象工厂设计模式及应用案例

引言 在软件开发中,合理的设计模式可以有效地提高代码的可维护性、可扩展性和可重用性。抽象工厂模式(Abstract Factory Pattern)便是一个重要的创建型设计模式,它允许我们在不指定具体类的情况下,创建一系列相关或相…...

LVS NAT模式实现三台RS的轮询访问

节点规划: 配置RS: RS1-RS3的网关配置均为 192.168.163.8 配置RS1: [rootlocalhost ~]# hostnamectl hostname rs1 [rootlocalhost ~]# nmcli c modify ens160 ipv4.method manual ipv4.addresses 192.168.163.7/24 ipv4.gateway 192.168.163.8 conne…...

LSM-Tree(Log-Structured Merge-Tree)详解

1. 什么是 LSM-Tree? LSM-Tree(Log-Structured Merge-Tree)是一种 针对写优化的存储结构,广泛用于 NoSQL 数据库(如 LevelDB、RocksDB、HBase、Cassandra)等系统。 它的核心思想是: 写入时只追加写(Append-Only),将数据先写入内存缓冲区(MemTable)。内存数据满后…...

uni-app jyf-parser将字符串转化为html 和 rich-text

uni-app jyf-parser将字符串转化为html-CSDN博客 方法二: rich-text | uni-app...

Docker+Ollama+Xinference+RAGFlow+Dify部署及踩坑问题

目录 一、Xinference部署 (一)简介 (二)部署 (三)参数 (四)错误问题 (五)Xinference配置Text-embedding模型 (六)Xinference配…...

CentOS 7 搭建基于匿名用户的 FTP 服务

1. 安装 VSFTPD yum install vsftpd -y 2. 配置 VSFTPD 编辑主配置文 vi /etc/vsftpd/vsftpd.conf 以下配置项存在或修改为对应值 anonymous_enableYES # 启用匿名用户 local_enableNO # 禁用本地用户 write_enableYES # 允许写入(若需要匿名上传&#xff0…...

【机器学习】什么是线性回归?

什么是线性回归? 线性回归是一种 监督学习算法,它通过拟合一个直线(或平面,高维空间下是超平面)来建立 输入特征 和 输出目标 之间的关系。简单来说,线性回归就是找出一个数学方程(通常是线性方…...

零、ubuntu20.04 安装 anaconda

1.anaconda下载 地址:Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 选择:Anaconda3-2023.07-2-Linux-x86_64.sh 2.anaconda安装 选择下载目录,选在在终端中打开,然后在终端输入安装命…...

Web纯前端实现在线打开编辑保存PPT幻灯片

很多项目中有时会需要在线打开PPT并编辑保存到服务器。猿大师办公助手可以完美调用本地office在线打开ppt文件,跟本地打开效果一样。还可以在线打开word、excel、pdf等文件,支持本机OFFICE完整嵌入模式,本机OFFICE所有功能基本都可以在网页上…...

LeetCode热题100精讲——Top3:最长连续序列【哈希】

你好,我是安然无虞。 文章目录 题目背景最长连续序列C解法Python解法 题目背景 如果大家对于 哈希 类型的概念并不熟悉, 可以先看我之前为此专门写的算法详解: 蓝桥杯算法竞赛系列第九章巧解哈希题,用这3种数据类型足矣 最长连续序列 题目链接&#x…...

vue2相关 基础命令

vue2 基础命令 vue简介,Vue 2 已于 2023 年 12 月 31 日停止维护。详见 Vue 2 终止支持 (EOL)。 安装完 Visual Studio Code后,打开项目目录, 在目录位置输入cmd,然后在命令行输入 code . 就可以在VScode打开项目。 公司的前后端…...

2025年渗透测试面试题总结-某 长亭(题目+回答)

网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 长亭 一、Spring SpEL表达式注入漏洞 1. 技术原理 2. 利用条件 3. 攻击方法 4. 防御策略 二、Jav…...

【web3】

检测钱包是否安装 方法一 // npm install metamask/detect-provider import detectEthereumProvider from metamask/detect-provider// 检测钱包是否安装 const isProvider await detectEthereumProvider() if(!isProvider) {proxy.$modal.msgError("请安装钱包")…...

Ubuntu部署Dufs文件服务器

安装dufs 安装cargo apt install cargo升级rust工具链 apt install rustup rustup update stable查看rust版本,需要>1.81 rustc --version安装dufs cargo install dufs将dufs加入环境变量 sudo vim ~/.bashrc export PATH"$HOME/.cargo/bin:$PATH" sou…...

速卖通API数据清洗实战:从原始JSON到结构化商品数据库

下面将详细介绍如何把速卖通 API 返回的原始 JSON 数据清洗并转换为结构化商品数据库。 1. 数据获取 首先要借助速卖通 API 获取商品数据,以 Python 为例,可使用requests库发送请求并得到 JSON 数据。 import requests# 替换为你的 API Key 和 Secret …...

前端模拟 websocket 请求小工具

背景: 后端写好websocket 接口后,用postman的某些版本无法直接模拟websocket请求,所以想着自制一个小工具。 使用方法: 直接复制以下代码到文本文件中,修改服务端端地址,保存为 .html的后缀名,…...

docker安装hyperf环境,连接本机redis问题处理

错误信息显示“Connection refused”,这通常说明 Docker 容器内的 Hyperf 项目无法连接到你本机的 Redis 服务。 1. 容器内的 127.0.0.1 指向问题 在 Docker 容器中,127.0.0.1 指的是容器本身,而不是宿主机(你的 Mac)…...

【极速版 -- 大模型入门到进阶】快速了解大型语言模型

文章目录 🌊 大模型作为一种生成式人工智慧,厉害在哪儿?-> 通用能力🌊 LLM 如何生成输出:简而言之就是文字接龙🌊 GPT 之前 ...:模型规模和数据规模概览🌊 ChatGPT 有三个训练阶段…...

精选10个好用的WordPress免费主题

10个好用的WordPress免费主题 1. Astra Astra 是全球最受欢迎的 WordPress 主题。它功能丰富,易于使用,SEO友好,是第一个安装量突破100万的非默认主题,并获得了5000多个五星好评。 它完美集成了Elementor、Beaver,古…...

算法日常刷题笔记(6)

重整旗鼓 第六篇笔记 第一天 使字符串平衡的最小交换次数 给你一个字符串 s ,下标从 0 开始 ,且长度为偶数 n 。字符串 恰好 由 n / 2 个开括号 [ 和 n / 2 个闭括号 ] 组成。 只有能满足下述所有条件的字符串才能称为 平衡字符串 : 字符串…...

【Unity3D脚本与系统设计6】鼠标触摸超时待机实现

实现步骤 在Unity中实现一个功能,当鼠标或触摸超过一定时间没有操作时,自动返回待机界面。 检测输入 首先,我需要检测用户的输入,无论是鼠标还是触摸。Unity的Input系统可以检测到鼠标和触摸事件,比如Input.GetAxis…...

【Spring篇】Spring的生命周期

一、Bean 生命周期的核心阶段 1. 实例化(Instantiation) • 触发时机:容器启动时(单例 Bean)或请求时(原型 Bean)。 • 实现方式: 通过反射(Class.newInstance() 或构造…...

C# 的Lambda表达式‌常见用法和示例

C# 的 ‌Lambda 表达式‌是一种强大的语法糖,能够极大简化代码并增强灵活性。以下是它的主要功能和应用场景,结合具体示例说明: 1. ‌简化委托实例化‌ Lambda 可以快速定义委托(如 Func、Action),无需显式…...

C++学习之路:从头搞懂配置VScode开发环境的逻辑与步骤

目录 编辑器与IDE基于vscode的C开发环境配置1. 下载vscode、浅尝编译。番外篇 2. 安装插件,赋能编程。3. 各种json文件的作用。c_cpp_properties.jsontask.jsonlaunch.json 总结&&彩蛋 编辑器与IDE 上一篇博客已经介绍过了C程序的一个编译流程,从…...

Web3与网络安全:如何确保去中心化应用的安全性

Web3与网络安全:如何确保去中心化应用的安全性 随着区块链技术的蓬勃发展,Web3的概念逐渐成为互联网发展的新趋势。Web3强调去中心化、用户主权和数据隐私,它的核心是构建一个更加开放、透明和安全的网络环境。然而,随着去中心化…...

插值法笔记 ——武汉理工统计 周

第二章 插值法 插值法定义 插值函数定义 设函数 y f ( x ) y f(x) yf(x) 在区间 [a,b] 上有定义&#xff0c;且满足节点排列&#xff1a; a ≤ x 0 < x 1 < ⋯ < x n ≤ b a \leq x_0 < x_1 < \cdots < x_n \leq b a≤x0​<x1​<⋯<xn​≤b …...

23种设计模式-命令(Command)设计模式

命令设计模式 &#x1f6a9;什么是命令设计模式&#xff1f;&#x1f6a9;命令设计模式的特点&#x1f6a9;命令设计模式的结构&#x1f6a9;命令设计模式的优缺点&#x1f6a9;命令设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是命令设计模式…...

和鲸科技执行总裁殷自强受邀主讲华中附属同济医院大模型应用通识首期课程

当前&#xff0c;医学与人工智能的深度融合正迎来历史性发展机遇。华中科技大学同济医学院附属同济医院&#xff08;以下简称“同济医院”&#xff09;作为医疗人工智能应用的先行探索者&#xff0c;已在电子病历辅助书写、科研数据分析、医疗合同自动化审核等关键场景完成试点…...

CI/CD(三) 安装nfs并指定k8s默认storageClass

一、NFS 服务端安装&#xff08;主节点 10.60.0.20&#xff09; 1. 安装 NFS 服务端 sudo apt update sudo apt install -y nfs-kernel-server 2. 创建共享目录并配置权限 sudo mkdir -p /data/k8s sudo chown nobody:nogroup /data/k8s # 允许匿名访问 sudo chmod 777 /dat…...

Centos 7 安装VNC服务

Centos 7 安装VNC服务 1. 安装 TigerVNC2. 设置 VNC 密码3. 创建并配置 x0vncserver 服务4. 启用并启动服务5. 检查服务状态6. 配置防火墙7. 连接 VNC问题1:出现无法安装可能是镜像源导致的。手动配置镜像源清除 YUM 缓存并重新加载 1. 安装 TigerVNC 确保已安装 TigerVNC 服务…...