Java 设计模式~工厂模式

在java开发,工厂模式应用场景有哪些?在Spring boot原码中 有哪些工厂类,并做相应的代码介绍。

工厂模式

工厂模式(Factory Pattern)是Java中一种常用的创建型设计模式,它提供了一种创建对象的最佳方式。此模式定义一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂模式让一个类的实例化延迟到其子类。

工厂模式的分类

  1. 简单工厂模式(Simple Factory Pattern)
    • 又称静态工厂方法模式,它不属于GOF的23种设计模式之一,但在实际开发中经常使用。
    • 通过一个工厂类来创建对象,客户端不需要直接实例化对象,而是通过调用工厂类的方法来获取对象实例。
  2. 工厂方法模式(Factory Method Pattern)
    • 定义一个用于创建对象的接口,但由子类决定要实例化的类是哪一个。
    • 工厂方法让一个类的实例化延迟到其子类,子类可以重写父类的工厂方法来指定实例化哪一个类。
  3. 抽象工厂模式(Abstract Factory Pattern)
    • 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    • 抽象工厂模式使得客户端可以独立于它的产品的具体类变化,客户端通过它们的抽象接口操纵实例。

工厂模式的优缺点

优点

  • 封装性:使用工厂模式可以将对象的创建过程封装起来,使得客户端代码与具体实现类解耦,降低了代码的耦合度。
  • 可扩展性:当需要添加新的产品时,只需要在工厂类中添加相应的创建逻辑即可,不需要修改客户端代码,符合开闭原则。
  • 灵活性:工厂模式可以灵活地创建对象,可以通过不同的工厂类来创建不同的对象实例。

缺点

  • 复杂性:增加了系统的复杂性,因为需要引入工厂类和抽象类或接口。
  • 性能开销:在创建对象时,需要调用工厂类的方法,可能会增加一些性能开销。

工厂模式的实现示例

以下是简单工厂模式的实现示例:

 

java复制代码

// 产品接口
public interface Product {
void use();
}
// 具体产品类A
public class ProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
// 具体产品类B
public class ProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 工厂类
public class SimpleFactory {
public static Product createProduct(String type) {
Product product = null;
switch (type) {
case "A":
product = new ProductA();
break;
case "B":
product = new ProductB();
break;
default:
throw new IllegalArgumentException("未知的产品类型");
}
return product;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.use();
Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}

在上面的示例中,SimpleFactory是一个简单工厂类,它有一个静态方法createProduct,根据传入的类型参数来创建不同的Product对象。客户端代码通过调用SimpleFactory.createProduct方法来获取产品对象,并调用其use方法。

通义灵码

在Java开发中,工厂模式有多种应用场景,主要集中在以下几个方面:

工厂模式的应用场景

  1. 解耦对象的创建和使用:通过工厂模式,客户端不需要知道对象的具体创建细节,只需要通过工厂获取对象即可。
  2. 动态选择对象的创建:可以根据不同的条件动态选择创建不同类型的对象。
  3. 集中管理对象的创建:适用于需要集中管理对象创建逻辑的场景。
  4. 简化复杂对象的创建过程:对于复杂的对象创建过程,可以使用工厂模式封装创建逻辑,简化客户端代码。
  5. 提高系统的可扩展性:新增产品类时,只需添加对应的工厂方法或工厂类,而不需要修改现有代码。

Spring Boot中的工厂类及其应用场景

1. BeanFactory
  • 应用场景BeanFactory是Spring框架的核心接口之一,负责管理和配置应用程序中的bean。它是Spring容器的基础,提供了基本的依赖注入功能。
  • 代码示例
     

    java

    // 获取BeanFactory实例 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); MyBean myBean = (MyBean) context.getBean("myBean");

2. ApplicationContext
  • 应用场景ApplicationContextBeanFactory的一个子接口,提供了更多的企业级功能,如国际化支持、事件传播机制等。它是Spring Boot中最常用的容器。
  • 代码示例
     

    java

    // 获取ApplicationContext实例 ApplicationContext context = SpringApplication.run(MyApplication.class, args); MyService myService = context.getBean(MyService.class);

3. ObjectFactory
  • 应用场景ObjectFactory通常用于延迟初始化对象,当需要时才创建对象。它常用于复杂的依赖关系中,以提高性能。
  • 代码示例
     

    java

    @Component public class MyComponent { private final ObjectFactory<MyDependency> myDependencyFactory; @Autowired public MyComponent(ObjectFactory<MyDependency> myDependencyFactory) { this.myDependencyFactory = myDependencyFactory; } public void doSomething() { MyDependency myDependency = myDependencyFactory.getObject(); // 使用myDependency } }

4. FactoryBean
  • 应用场景FactoryBean接口允许自定义bean的创建逻辑。当你需要复杂的bean初始化过程时,可以实现这个接口。
  • 代码示例
     

    java

    @Component public class MyFactoryBean implements FactoryBean<MyBean> { @Override public MyBean getObject() throws Exception { return new MyBean(); // 自定义创建逻辑 } @Override public Class<?> getObjectType() { return MyBean.class; } }

5. SmartFactoryBean
  • 应用场景SmartFactoryBeanFactoryBean的一个扩展接口,提供了更多的控制选项,如是否单例、是否需要运行时检查等。
  • 代码示例
     

    java

    @Component public class MySmartFactoryBean implements SmartFactoryBean<MyBean> { @Override public MyBean getObject() throws Exception { return new MyBean(); // 自定义创建逻辑 } @Override public Class<?> getObjectType() { return MyBean.class; } @Override public boolean isSingleton() { return true; // 是否为单例 } }

Spring Boot源码中的工厂类示例

DefaultListableBeanFactory
  • 应用场景DefaultListableBeanFactoryBeanFactory的一个实现类,提供了对bean定义的注册和管理功能。
  • 代码示例
     

    java

    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); BeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions(new FileSystemResource("beans.xml")); MyBean myBean = (MyBean) beanFactory.getBean("myBean");

AnnotationConfigApplicationContext
  • 应用场景AnnotationConfigApplicationContextApplicationContext的一个实现类,用于从Java配置类中加载bean定义。
  • 代码示例
     

    java

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MyService myService = context.getBean(MyService.class);

SimpleObjectFactory
  • 应用场景SimpleObjectFactory是Spring内部使用的简单对象工厂,用于创建对象实例。
  • 代码示例
     

    java

    SimpleObjectFactory factory = new SimpleObjectFactory(); MyBean myBean = factory.createObjectInstance(MyBean.class);

AutowireCapableBeanFactory
  • 应用场景AutowireCapableBeanFactoryBeanFactory的一个扩展接口,提供了自动装配功能。
  • 代码示例
     

    java

    AutowireCapableBeanFactory beanFactory = new DefaultListableBeanFactory(); MyBean myBean = beanFactory.createBean(MyBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);

这些工厂类在Spring Boot中扮演着重要的角色,帮助开发者更高效地管理和创建对象。根据具体的应用场景,可以选择合适的工厂类来实现需求。

文兴一言

Java开发中工厂模式的应用场景

工厂模式在Java开发中具有广泛的应用场景,主要包括以下几个方面:

  1. 对象创建复杂:当对象的创建过程涉及多个步骤或需要复杂的配置时,可以使用工厂模式来封装这些创建逻辑,简化客户端代码。
  2. 需要创建的对象类型较多:如果系统中需要根据不同的条件创建不同类型的对象,使用工厂模式可以避免大量的if-else或switch-case语句,使代码更加清晰和易于维护。
  3. 提高代码的可测试性:在单元测试时,工厂模式允许创建模拟(mock)对象,以便在不依赖实际对象的情况下测试代码。
  4. 遵循开闭原则:工厂模式使得系统能够在不修改现有代码的情况下添加新的产品类型或创建逻辑,符合开闭原则(对扩展开放,对修改关闭)。

Spring Boot源码中的工厂类

在Spring Boot源码中,工厂模式得到了广泛的应用。以下是一些常见的工厂类及其代码介绍:

  1. SpringFactoriesLoader

    SpringFactoriesLoader是Spring Boot用于加载工厂类的关键类。它负责从类路径中的META-INF/spring.factories文件中加载工厂类的名称,并实例化这些工厂类。这个文件以键值对的形式存在,键是接口类的全限定名,值是用逗号隔开的多个实现类的全限定名。

     

    java复制代码

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    // Use names and ensure unique to protect against duplicates
    Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
    }

    在上面的代码中,getSpringFactoriesInstances方法负责加载和实例化spring.factories文件中指定的工厂类。

  2. ApplicationContextInitializer工厂

    ApplicationContextInitializer是Spring Boot用于初始化ApplicationContext的接口。Spring Boot在启动时会加载并调用这些初始化器来配置ApplicationContext。这些初始化器通常通过@Configuration注解定义的配置类来创建。

     

    java复制代码

    @Configuration
    public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
    // 初始化逻辑
    }
    }

    spring.factories文件中,可以通过指定org.springframework.context.ApplicationContextInitializer的键来注册这些初始化器。

  3. ApplicationListener工厂

    ApplicationListener是Spring框架中的事件监听器接口。在Spring Boot中,可以通过实现这个接口来监听特定的事件,并在事件发生时执行相应的逻辑。这些监听器通常也是通过@Configuration注解定义的配置类来创建的。

     

    java复制代码

    @Component
    public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
    // 事件处理逻辑
    }
    }

    ApplicationContextInitializer类似,ApplicationListener也可以通过在spring.factories文件中指定相应的键来注册。

  4. 自定义工厂类

    除了Spring Boot自带的工厂类外,开发者还可以根据自己的需求创建自定义的工厂类。这些工厂类通常用于封装复杂的对象创建逻辑,以便在需要时轻松地创建对象实例。

     

    java复制代码

    @Configuration
    public class MyFactoryConfig {
    @Bean
    public MyService myService() {
    return new MyServiceImpl();
    }
    }
    public interface MyService {
    void performService();
    }
    public class MyServiceImpl implements MyService {
    @Override
    public void performService() {
    // 服务实现逻辑
    }
    }

    在上面的代码中,MyFactoryConfig是一个配置类,它定义了一个工厂方法myService来创建MyService接口的实现类MyServiceImpl的实例。这样,当需要MyService类型的对象时,Spring容器会自动调用这个工厂方法来创建实例。

综上所述,工厂模式在Java开发和Spring Boot源码中都具有广泛的应用。通过合理地使用工厂模式,可以简化对象创建逻辑、提高代码的可读性和可维护性,并遵循开闭原则以支持系统的扩展性。 

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

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

相关文章

【操作系统】实验二:观察Linux,使用proc文件系统

实验二 观察Linux&#xff0c;使用proc文件系统 实验目的&#xff1a;学习Linux内核、进程、存储和其他资源的一些重要特征。读/proc/stat文件&#xff0c;计算并显示系统CPU占用率和用户态CPU占用率。&#xff08;编写一个程序使用/proc机制获得以及修改机器的各种资源参数。…

day2 数据结构 结构体的应用

思维导图 小练习&#xff1a; 定义一个数组&#xff0c;用来存放从终端输入的5个学生的信息【学生的信息包含学生的姓名、年纪、性别、成绩】 1>封装函数 录入5个学生信息 2>封装函数 显示学生信息 3>封装函数 删除第几个学生信息&#xff0c;删除后调用显示学…

SQL Server:只有MDF文件,如何附加数据库

第一步&#xff1a;先新建一个同名数据库&#xff0c;然后停止sql服务&#xff0c;删除新建数据库.ldf文件。 第二步&#xff1a;将要附加的数据库的.mdf文件覆盖刚新建的.mdf文件&#xff0c;并重启sql服务。 第三步&#xff1a;这时数据库DATA目录下只有一个.mdf文件&#xf…

React开发高级篇 - React Hooks以及自定义Hooks实现思路

Hooks介绍 Hooks是react16.8以后新增的钩子API&#xff1b; 目的&#xff1a;增加代码的可复用性&#xff0c;逻辑性&#xff0c;弥补无状态组件没有生命周期&#xff0c;没有数据管理状态state的缺陷。 为什么要使用Hooks&#xff1f; 开发友好&#xff0c;可扩展性强&#…

jmeter调整字号无法生效?

调整之前如上图&#xff0c;字体非常小&#xff0c;哪怕我设置的字号是48 查阅了资料&#xff0c;试了几次&#xff0c;解决办法如下&#xff1a; 用编辑器打开jmeter.bat 在echo off的下一行添加以下代码 set JVM_ARGS%JVM_ARGS% -Dswing.plaf.metal.controlFontDialog-20…

密码学——密码学基础、散列函数与数字签名

1.密码学概述 是信息安全的基础和核心&#xff0c;是防范各种安全威胁的重要手段&#xff0c;信息安全的许多相关知识都与密码学相关。 密码学发展 密码学是一门古老而又年轻的学科 &#xff0c;几千年以前就存在&#xff0c;至今仍在发展演进。地位非常重要甚至起决定性作用…

CSS的颜色表示方式

以下介绍几种常见的CSS颜色表示方式&#xff1a; 颜色名称 html和css规范中定义了147种可用的颜色名用的相对较少 16进制表示 css三原色&#xff1a;红、绿、蓝16进制的颜色值&#xff1a; #rrggbb16进制整数规定颜色成分&#xff0c;所有的值均介于 00 - ff 之间&#xff…

知识图谱8:深度学习各种小模型

1、知识图谱的展示有很多工具 Neo4j Browser - - - - 浏览器版本 Neo4j Desktop - - - - 桌面版本 graphX - - - - 可以集成到Neo4j Desktop Neo4j 提供的 Neo4j Bloom 是用户友好的可视化工具&#xff0c;适合非技术用户直观地浏览图数据。Cypher 是其核心查询语言&#xf…

Python | 数据可视化中常见的4种标注及示例

在Python的数据可视化中&#xff0c;标注&#xff08;Annotation&#xff09;技术是一种非常有用的工具&#xff0c;它可以帮助用户更准确地解释图表中的数据和模式。在本文中&#xff0c;将带您了解使用Python实现数据可视化时应该了解的4种标注。 常见的标注方式 文本标注箭…

在Goland中对goroutine协程断点调试

在Goland中对goroutine协程断点调试 环境: Goland 参考了 chatgpt 的回复 进行断点调试的代码 package mainimport ("fmt""sync""time" )// worker 模拟处理任务 func worker(id int, wg *sync.WaitGroup) {defer wg.Done() // 确保任务完成后…

深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

目录 深入理解 JavaScript 中的 Array.find() 方法&#xff1a;原理、性能优势与实用案例详解 一、引言&#xff1a;为什么要使用Array.find() 二、Array.find()的使用与技巧 1、基础语法 2、返回值 3、使用技巧 三、Array.find()的优势与实际应用案例 1、利用返回引用…

Docker 安装 Jenkins:2.346.3

准备&#xff1a;已安装Docker&#xff0c;已配置服务器安全组规则 1581 1、拉取镜像 [rootTseng ~]# docker pull jenkins/jenkins:2.346.3 2.346.3: Pulling from jenkins/jenkins 001c52e26ad5: Pull complete 6b8dd635df38: Pull complete 2ba4c74fd680: Pull complet…

在 Linux 和 Windows 操作系统下查询局域网IP

以下分别介绍在 Linux 和 Windows 操作系统下进行局域网 IP 查询的常用方法及相应代码示例&#xff1a; Linux 系统——查询局域网 IP 使用 ifconfig 命令&#xff08;较旧但常用方式&#xff0c;在多数 Linux 发行版中可用&#xff09; ifconfig 命令可以用来查看网络接口的配…

web 自动化 selenium

1、下载Chrome对应的driver版本 我的chrome是 131.0.6778.109&#xff0c;我下载的driver是131.0.6778.69&#xff08;想找一模一样的&#xff0c;但是没有&#xff09; https://googlechromelabs.github.io/chrome-for-testing/ chromedriver下载 2、配置Chrome deriver及 …

opencv实现元素的图片坐标定位

桌面应用程序的UI自动化&#xff0c;除了解析应用层级控件外&#xff0c;还可以通过图片定位获取目标元素位置&#xff0c;对其进行点击、双击、滚动等操作。 python可用opencv库操作图片。 opencv安装 sudo apt install python-opencv 图片比对 import cv2 import pyautog…

Datawhale AI 冬令营(第一期)定制你的第一个专属模型-学习笔记

最近我报名参加了Datawhale组织的主题为“动手学系列&#xff0c;人人都能应用的AI”的Datawhale AI冬令营&#xff08;第一期&#xff09;。 本次学习一共12天&#xff0c;从12月10日-12月21日&#xff0c;学习会包含【跑通速通手册】&#xff0c;【学习大模型微调&数据集…

异常安全重启运行机制:健壮的Ai模型训练自动化

文章目录 前言一、热力图主函数代码1、正规N图热力图运行代码2、重新迭代循环求解方法 二、中断重启继续推理或训练1、封装含参主函数2、终止重启进程管理方法1、终止启动源码2、源码解读 三、终止启动主函数源码解读1、终止启动源码2、源码解读关键点解析 四、完整代码Demo1、…

Spring项目中常用的配置(含yml和properties)

MyBatis和数据库配置相关 yml&#xff1a; spring:application:name: Test # Spring项目名称,记得修改datasource:url: jdbc:mysql://127.0.0.1:3306/test?characterEncodingutf8&useSSLfalse # test为数据库名,记得修改username: root # 数据库用户名,记得修改password…

Redis01

springbootredis 特点 1.高效性 2.支持多种数据结构 String,list,set,hash.zset 3.稳定性&#xff1a;持久化&#xff0c;主从复制&#xff08;集群&#xff09; 4.其他特性&#xff1a;支持过期时间&#xff0c;支持事务&#xff0c;消息订阅。 安装 1.下载安装包 redis官…

【Unity】Amplify Shader Editor

Amplify Shader Editor (ASE) Amplify Shader Editor&#xff0c;是一个功能强大的基于节点的着色器开发工具&#xff0c;允许开发者在 Unity 中轻松创建和管理复杂的 Shader。 主要功能和特点 基于节点的编辑器&#xff1a; • 提供直观的可视化界面&#xff0c;减少手写 Sh…