【设计模式系列】简单工厂模式

一、什么是简单工厂模式

简单工厂模式(Simple Factory Pattern)是一种设计模式,其中包含一个工厂类,根据传入的参数不同,返回不同类的实例。这个工厂类封装了对象的创建逻辑,使得客户端代码可以从直接创建对象的复杂性中解放出来。

二、简单工厂模式的角色

  1. 抽象产品(Product)

    • 定义了产品的接口或者抽象类,所有的具体产品类都应该实现这个接口或继承这个抽象类。
    • 它规定了具体产品对象必须实现的接口。
  2. 具体产品(Concrete Product)

    • 实现了抽象产品接口的具体产品类。
    • 工厂模式创建的最终对象,是具体产品类的实例。
  3. 抽象工厂(Creator)

    • 提供了一个创建产品的接口,用于创建和返回一个产品实例。
    • 它可能包含一个或多个创建产品对象的方法。
  4. 具体工厂(Concrete Creator)

    • 实现了抽象工厂接口的具体工厂类。
    • 它负责实例化具体的产品对象,并且返回一个产品实例。

三、简单工厂模式的典型应用场景

  1. 对象的创建需要灵活性: 当对象的创建依赖于多个条件,或者需要根据不同的输入参数来创建不同类型的对象时,工厂模式提供了一种灵活的方式来处理这些情况。

  2. 创建对象成本较高: 当对象的创建过程中涉及到复杂的逻辑或者资源消耗较大时,使用工厂模式可以封装这些复杂的创建过程,使得客户端代码更加简洁。

  3. 数据库连接池: 在需要创建数据库连接时,可以使用工厂模式来封装创建连接的过程,同时可以管理连接的生命周期。

四、简单工厂模式在StaticListableBeanFactory中的应用

StaticListableBeanFactory 是 Spring 框架中 BeanFactory 接口的一个具体实现,它是一种特殊类型的工厂,用于存储和管理 bean 的实例。在工厂模式中,工厂类负责创建对象,而在 StaticListableBeanFactory 中,这个对象就是 Spring 容器管理的 bean。这个工厂是一个静态的工厂,意味着它不基于 bean 的定义来动态创建 bean,而是在工厂初始化时就添加了所有 bean 的实例。

在工厂模式的应用中,StaticListableBeanFactory 扮演了以下几个角色:

  1. 抽象工厂(Factory):提供了一个接口或抽象类,定义了创建对象的方法。在 StaticListableBeanFactory 中,这个接口是由 BeanFactory 提供的,它定义了 getBean 等方法来获取 bean 实例。

  2. 具体工厂(Concrete Factory):实现了工厂接口的具体类,负责创建具体产品的对象。StaticListableBeanFactory 就是具体工厂的实现,它通过 addBean 方法静态地添加 bean 实例。

  3. 抽象产品(Product):工厂模式中创建的对象。在 Spring 中,这些对象就是由 StaticListableBeanFactory 管理的 bean。

  4. 具体产品(Concrete Product):实现了产品接口的具体类。在 Spring 的上下文中,这些是由 StaticListableBeanFactory 管理的具体 bean 实例。

StaticListableBeanFactory 在工厂模式中的应用特点如下:

  • 静态实例管理StaticListableBeanFactory 存储的是 bean 的实例,而不是基于 bean 定义来动态创建实例。这意味着所有的 bean 必须在工厂初始化时就已经存在。

  • 单例管理StaticListableBeanFactory 只支持单例 bean,不支持原型(prototype)bean。这是因为它在初始化时就已经创建了 bean 的实例,并且存储起来供后续使用。

  • 列表功能:由于实现了 ListableBeanFactory 接口,StaticListableBeanFactory 支持通过类型来检索 bean,这允许客户端代码可以通过类型来获取所有匹配的 bean 列表。

  • 简单性StaticListableBeanFactory 是一个简化版的 bean 工厂,它不支持 bean 的生命周期管理、依赖注入、bean 后处理等高级功能,因此适用于简单的应用场景。

下面是一个简单的示例,展示了如何使用 StaticListableBeanFactory 来实现工厂模式:

//抽象工厂
public interface BeanFactory {

	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	Object getBean(String name, Object... args) throws BeansException;

}

//具体工厂
public class StaticListableBeanFactory implements BeanFactory {

	@Override
	public Object getBean(String name) throws BeansException {
		String beanName = BeanFactoryUtils.transformedBeanName(name);
		Object bean = this.beans.get(beanName);

		if (bean == null) {
			throw new NoSuchBeanDefinitionException(beanName,
					"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
		}

		if (BeanFactoryUtils.isFactoryDereference(name) && !(bean instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, bean.getClass());
		}

		if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
			try {
				return ((FactoryBean<?>) bean).getObject();
			}
			catch (Exception ex) {
				throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
			}
		}
		else {
			return bean;
		}
	}

	public void addBean(String name, Object bean) {
		this.beans.put(name, bean);
	}

}

// 具体产品
class MyBean {
    public void doSomething() {
        System.out.println("Doing something");
    }
}

//客户端
public class StaticListableBeanFactoryExample {

    public static void main(String[] args) {
        // 创建 StaticListableBeanFactory 实例
        StaticListableBeanFactory beanFactory = new StaticListableBeanFactory();

        // 创建一个具体的产品实例
        MyBean myBean = new MyBean();

        // 将产品实例添加到工厂中,关联一个名称
        beanFactory.addBean("myBeanName", myBean);

        // 从工厂中获取产品实例
        MyBean bean = beanFactory.getBean("myBeanName", MyBean.class);

        // 使用产品
        bean.doSomething();
    }
}

在这个示例中,MyBean 是具体产品,我们创建了它的一个实例,并将其添加到 StaticListableBeanFactory 中。然后,我们可以通过工厂的 getBean 方法来获取这个 bean 并使用它。这个过程展示了工厂模式的典型应用,即通过工厂来封装对象的创建过程,使得客户端代码更加简洁,并且解耦了对象的创建和使用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSDN Markdown 编辑器语法大全

Markdown 是一种轻量级标记语言&#xff0c;它以简洁、易读易写的特点&#xff0c;被广泛应用于技术文档、博客文章、笔记等领域。CSDN 的 Markdown 编辑器为用户提供了丰富的功能&#xff0c;让用户能够轻松地创建格式规范、内容丰富的文档。以下是一份详细的 CSDN Markdown 编…

Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题

作者&#xff1a;彦鸿 背景 随着 LLM&#xff08;大语言模型&#xff09;技术的不断成熟和应用场景的不断拓展&#xff0c;越来越多的企业开始将 LLM 技术纳入自己的产品和服务中。LLM 在自然语言处理方面表现出令人印象深刻的能力。然而&#xff0c;其内部机制仍然不明确&am…

本地大模型部署和基于RAG方案的私有知识库搭建

背景与目的 在人工智能领域&#xff0c;大语言模型如GPT系列、BERT等&#xff0c;以其强大的语言生成与理解能力&#xff0c;正在深刻改变着我们的工作与生活方式。这些模型通过海量数据训练而成&#xff0c;能够执行从文本生成、问答系统到代码编写等多种任务。然而&#xff…

目标检测——yolov5-3.1的环境搭建和运行

第一步&#xff1a;安装anaconda环境&#xff0c;并且配置好cuda&#xff0c;安装需要的基本包 查看对应cuda版本&#xff0c;后续下载cudatoolkit需要对应版本 nvcc -V 第二步&#xff1a;创建虚拟环境&#xff0c;激活环境&#xff0c;安装所需的包 conda create -n yolo…

V2X介绍

文章目录 什么是V2XV2X的发展史早期的DSRC后起之秀C-V2XC-V2X 和DSRC 两者的对比 什么是V2X 所谓V2X&#xff0c;与流行的B2B、B2C如出一辙&#xff0c;意为vehicle to everything&#xff0c;即车对外界的信息交换。车联网通过整合全球定位系统&#xff08;GPS&#xff09;导…

一个非常有趣的问题——链表带环问题

目录 前言 一、为什么快指针每次⾛两步&#xff0c;慢指针⾛⼀步可以相遇&#xff0c;有没有可能遇不上 二、快指针⼀次⾛3步&#xff0c;⾛4步&#xff0c;...n步⾏吗? 三、求环形链表中入环的节点 前言 在学习链表的时候我发现一个一个非常有趣的问题链表带环&#xff0c;…

重生之我爱上了k8s!

内容不全&#xff0c;待补充中...... 目录 一、k8s的部署 1.1.集群环境初始化 1.1.1.所有主机禁用swap 1.1.2.安装k8s部署工具 1.1.2.所有节点安装cri-docker 1.1.3.在master节点拉取K8S所需镜像 1.1.4.集群初始化 1.1.5.其他两台主机加入集群 1.1.6.安装flannel网络…

UE4 材质学习笔记12(水体反射和折射)

一.水体反射和折射 首先就是要断开所有连接到根节点的线&#xff0c;因为水有很多不同的节点成分&#xff0c;当所有其他节点都在用时 要分辨出其中一个是何效果是很难的。 虚幻有五种不同的方法可以创建反射&#xff0c;虚幻中的大多数场景使用多种这些方法 它们会同时运作。…

串口头汇总

1 网线头 1 4对应485A &#xff0c; 2 5对应485B &#xff0c;1 4 接在一起&#xff0c;2 5 接在一起转成2根线也可以。 ----------拓展中

简单介绍冯诺依曼体系

现代的计算机, 大多遵守冯诺依曼体系结构 CPU中央处理器&#xff1a;进行算术运算和逻辑判断。存储器&#xff1a;分为外存和内存&#xff0c;用于存储数据&#xff08;使用二进制方式存储&#xff09;。输入设备&#xff1a;用户给计算机发号施令。输出设备&#xff1a;计算机…

【记录】Android|安卓平板 猫游戏(四款,peppy cat,含下载教程和链接)

前言 网上大部分直接找到的都是 iPad 的猫游戏&#xff0c;安卓的要查英文才找得到&#xff0c;但质量也都一般&#xff0c;或不知道在哪里下载。 遂自己找。 下载测试时间&#xff1a;2024/10/20 文章目录 前言1 检索2 亲测2.1 ✅⭐⭐⭐⭐⭐Cat Alone 1 and 22.2 &#x1f4…

Qt中使用线程之moveToThread

步骤&#xff1a; 1、创建一个自定义Worker类&#xff0c;继承自QObject 2、主线程中创建QThread的对象&#xff0c;Worker类的对象 3、Worker类的对象调用moveToThread函数移动到QThread的对象中 4、主线程自定义一个信号&#xff0c;并使用信号槽连接到worker类对象的任务…

身份和访问管理平台(IAM)是数字身份管理的关键路径和重要方法

随着数字化转型不断推进&#xff0c;越来越多的企业选择通过身份和访问管理平台&#xff08;IAM&#xff09;来管理数字身份。IAM不只是传统的账号、认证、授权、审计产品&#xff0c;更是数字身份管理的创新领航者&#xff0c;以权威数字身份为基础&#xff0c;结合用户与数字…

Python爬取京东商品信息,详细讲解,手把手教学(附源码)

Python 爬虫爬取京东商品信息 下面我将逐一解释每一部分的代码 导入库 from selenium import webdriver from selenium.webdriver.edge.service import Service from selenium.webdriver.edge.options import Options import time import random import csv from selenium.c…

VMware中Ubuntu安装

VMware官网&#xff1a;https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion 先在官网下载VMware&#xff0c;一直根据默认点下一步就好了&#xff0c;记得更改安装地址哦&#xff0c;否则默认下在C盘里。 先下载好Ubuntu映像文件&#xff1a;https://…

[电子科大]王丽杰 离散数学 第二讲 特殊集合和集合间关系 笔记

1.2 特殊集合与集合间关系 空集 不含任何元素的集合叫做空集(empty set)&#xff0c;记作∅. 空集可以符号化为 ∅ { x ∣ x ≠ x } ∅ \{ x|x ≠ x\} ∅{x∣x​x} . 空集是绝对唯一的。 全集 针对一个具体范围&#xff0c;我们考虑的所有对象的集合叫做全集(universal …

JMeter模拟并发请求

PostMan不是严格意义上的并发请求工具&#xff0c;实际是串行的&#xff0c;如果需要测试后台接口并发时程序的准确性&#xff0c;建议采用JMeter工具。 案例&#xff1a;JMeter设置20个并发卖票请求&#xff0c;查看后台是否存在超卖的情况 方式一&#xff1a;一共10张票&…

视觉分析在烟火检测中的应用

随着城市化进程的加快&#xff0c;烟火安全问题日益突出。传统的烟火检测方式依赖人工巡查和基础传感器&#xff0c;容易受到人为因素和环境条件的影响&#xff0c;导致检测效率低下和误报率高。为了解决这一问题&#xff0c;烟火检测算法的引入为我们提供了一种全新的解决方案…

前端根据某数组是否有数据渲染按钮

代码&#xff1a;React TypeScript 由于这个data可能是undefined&#xff0c;所以报错了&#xff0c;问了chatgpt&#xff0c;可以进行的检查方式有以下几种&#xff1a; 1、使用可选链 或者这样写&#xff1a; 我个人比较喜欢用第二种&#xff0c;因为比较简洁 2、类型守卫…

python中使用库pandas来创建excel表格

先需要pip或者conda下载这个pandas 源码如下&#xff1a; import pandas as pdsList_1 [1,2,3,4,5] List_2 [软件,硬件,结构,产品经理,项目经理] List_3 [杭州,南京,河南,合肥,成都] List_4 [21,22,23,24,25] List_5 [2000,3000,1400,1500,2000]TitleData { # 用字典设…