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

【设计模式】工厂模式(创建型)⭐⭐⭐

文章目录

  • 1.概念
    • 1.1 什么是工厂模式
    • 1.2 优点与缺点
  • 2.实现方式
    • 2.1 简单工厂模式(Simple Factory)
    • 2.2 简单工厂模式缺点
    • 2.3 抽象工厂模式(Abstract Factory Pattern)
  • 3 Java 哪些地方用到了工厂模式
  • 4 Spring 哪些地方用到了工厂模式

1.概念

1.1 什么是工厂模式

工厂模式属于创建型模式。它的主要目的是提供一个创建对象的接口,而不直接实例化对象。这样可以将对象的创建和使用分离,降低系统的耦合度,提高系统的灵活性和可扩展性。

1.2 优点与缺点

优点:
1.降低了系统中对象的耦合度,提高了系统的灵活性。
2.增加了系统的可扩展性,当增加新的产品时,只需扩展一个工厂类即可。
3.隔离了具体产品的创建,使得代码符合单一职责原则。
缺点:
1.增加了系统的复杂度,因为引入了新的工厂类层次。
2.如果产品等级结构过于复杂,那么工厂方法模式的类层次也会相当复杂。

2.实现方式

2.1 简单工厂模式(Simple Factory)

① 定义产品接口或抽象类

public interface Product {void operate();
}

② 实现具体产品类:接着,我们创建具体的产品类,它们实现了产品接口或继承了抽象类。

public class ConcreteProductA implements Product {@Overridepublic void operate() {System.out.println("ConcreteProductA operates.");}
}public class ConcreteProductB implements Product {@Overridepublic void operate() {System.out.println("ConcreteProductB operates.");}
}

③ 创建工厂类:然后,我们创建一个工厂类,它提供一个静态方法来创建产品对象。工厂方法根据传入的参数来决定创建哪个具体产品类的实例。

public class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ConcreteProductA();} else if ("B".equals(type)) {return new ConcreteProductB();}return null;}
}

④ 客户端代码:最后,客户端代码通过调用工厂类的静态方法来获取产品实例,而不是直接创建产品对象。

public class Client {public static void main(String[] args) {Product productA = SimpleFactory.createProduct("A");Product productB = SimpleFactory.createProduct("B");productA.operate();productB.operate();}
}

这种实现方式使得客户端代码与具体产品类的实现解耦,提高了系统的灵活性和可扩展性。如果需要增加新的产品类,只需要扩展新的具体产品类,并在工厂类中增加相应的创建逻辑,而不需要修改客户端代码。

2.2 简单工厂模式缺点

违反开闭原则:简单工厂模式的工厂方法集中了所有产品的创建逻辑。当需要增加新的产品时,必须修改工厂方法来实现新的逻辑,这违反了开闭原则(软件实体应该对扩展开放,对修改关闭)。
工厂方法单一职责原则:随着产品种类增加,工厂方法会变得越来越复杂,包含大量的条件分支语句。这使得工厂类承担了过多的责任,违反了单一职责原则(一个类应该只有一个引起它变化的原因)。
扩展困难:由于工厂类集中了所有产品的创建逻辑,当产品种类很多时,工厂类会变得非常庞大,难以维护和扩展。
依赖集中:客户端代码依赖于工厂类,如果工厂类发生变化,可能会影响到客户端代码。
不利于产品类的解耦:虽然简单工厂模式将客户端的创建逻辑和产品类的实现解耦,但是产品类和工厂类之间的耦合度仍然较高,因为工厂类需要知道所有产品类的具体实现。
不利于反射和依赖注入:由于工厂类内部硬编码了产品类的创建逻辑,这使得在运行时难以通过反射或依赖注入的方式来动态地创建和替换产品对象。

2.3 抽象工厂模式(Abstract Factory Pattern)

① 定义抽象工厂接口:声明了一组用于创建抽象产品对象的方法。

public interface AbstractFactory {AbstractProductA createProductA();AbstractProductB createProductB();
}

② 实现具体工厂类:实现了抽象工厂接口,每个具体工厂都负责创建自己产品系列中的对象。

public class ConcreteFactory1 implements AbstractFactory {@Overridepublic AbstractProductA createProductA() {return new ConcreteProductA1();}@Overridepublic AbstractProductB createProductB() {return new ConcreteProductB1();}
}public class ConcreteFactory2 implements AbstractFactory {@Overridepublic AbstractProductA createProductA() {return new ConcreteProductA2();}@Overridepublic AbstractProductB createProductB() {return new ConcreteProductB2();}
}

③ 定义抽象产品接口:声明了产品的公共接口。

public interface AbstractProductA {void usefulFunctionA();
}public interface AbstractProductB {void usefulFunctionB();
}

④ 实现具体产品类:实现了抽象产品接口,每个具体产品都属于一个产品系列。

public class ConcreteProductA1 implements AbstractProductA {@Overridepublic void usefulFunctionA() {// 具体实现}
}public class ConcreteProductA2 implements AbstractProductA {@Overridepublic void usefulFunctionA() {// 具体实现}
}public class ConcreteProductB1 implements AbstractProductB {@Overridepublic void usefulFunctionB() {// 具体实现}
}public class ConcreteProductB2 implements AbstractProductB {@Overridepublic void usefulFunctionB() {// 具体实现}
}

⑤ 客户端代码:客户端通过抽象工厂接口来创建产品,而不需要关心具体工厂和产品的实现细节。

public class Client {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();AbstractProductA productA1 = factory1.createProductA();AbstractProductB productB1 = factory1.createProductB();productA1.usefulFunctionA();productB1.usefulFunctionB();AbstractFactory factory2 = new ConcreteFactory2();AbstractProductA productA2 = factory2.createProductA();AbstractProductB productB2 = factory2.createProductB();productA2.usefulFunctionA();productB2.usefulFunctionB();}
}

3 Java 哪些地方用到了工厂模式

Java AWT(Abstract Window Toolkit):AWT中的 Button, TextField, Label 等组件在不同的操作系统上会有不同的外观和行为。AWT使用抽象工厂模式来创建这些组件,以便它们可以根据运行平台的不同而自动适配。
Java Swing:与AWT类似,Swing组件也使用了抽象工厂模式来创建组件,以便它们可以根据不同的Look and Feel(比如Windows, Motif, Metal等)来改变外观。
JDBC(Java Database Connectivity):JDBC使用抽象工厂模式来创建数据库连接。DriverManager 类充当抽象工厂,它根据URL的不同来创建不同数据库的连接(例如MySQL, Oracle, SQL Server等)。
Java XML解析:在解析XML文档时,可以使用抽象工厂模式来创建不同的解析器。例如,可以根据需要创建SAX或DOM解析器的实例。
Java国际化(Internationalization, I18N):在处理国际化时,可以使用抽象工厂模式来创建不同语言环境的资源包。
Java Logging API:Java的日志记录框架(如Log4j, SLF4J等)通常使用抽象工厂模式来创建日志记录器实例,以便可以根据配置动态地选择不同的日志实现。
Spring Framework:Spring框架广泛使用了抽象工厂模式来创建bean。例如,BeanFactory 和 ApplicationContext 都是抽象工厂,它们负责根据配置文件或注解来创建和管理bean的生命周期。
Java ImageIO:ImageIO 类是一个抽象工厂,用于创建图像输入/输出处理的流。它可以根据图像格式(如JPEG, PNG, GIF等)来创建相应的图像读取器和写入器。

4 Spring 哪些地方用到了工厂模式

BeanFactory:BeanFactory 是Spring中最基本的抽象,它是一个工厂模式的实现,负责创建和管理bean的生命周期。BeanFactory 根据配置信息来创建bean,并且可以管理bean之间的依赖关系。
ApplicationContext:ApplicationContext 是 BeanFactory 的超集,它也实现了工厂模式。与 BeanFactory 相比,ApplicationContext 提供了更多的功能,如事件传播、资源加载、国际化消息处理等。
FactoryBean:Spring提供了一个名为 FactoryBean 的接口,允许开发者创建自己的工厂来生成复杂的对象。实现这个接口的类可以作为工厂,Spring容器会调用其 getObject 方法来获取bean实例。
ObjectFactory:ObjectFactory 是一个简单的工厂接口,它只有一个方法 getObject。这个接口通常用于延迟加载场景,可以在需要的时候才创建对象。
JdbcTemplate 和数据源:Spring的 JdbcTemplate 类依赖于数据源来获取数据库连接。数据源的创建通常是通过工厂模式来实现的,可以根据配置动态地创建不同类型的数据源实例。
事务管理:Spring的事务管理也使用了工厂模式。例如,TransactionManager 是一个抽象工厂,它根据配置来创建和管理事务。
AOP代理创建:Spring的AOP框架使用工厂模式来创建代理对象。根据配置的不同,Spring可以创建JDK动态代理或CGLIB代理。
消息服务:Spring的JMS模块使用工厂模式来创建消息生产者和消费者。
资源加载:Spring的 ResourceLoader 是一个抽象工厂,它根据资源路径来创建 Resource 对象。
事件发布:Spring的事件发布机制也使用了工厂模式,ApplicationEventPublisher 负责创建和发布事件。
Spring框架的设计哲学之一就是依赖注入(DI),它允许将对象之间的依赖关系外部化,由容器来管理。工厂模式是实现依赖注入的关键机制之一,它允许Spring容器根据配置来创建和管理对象,从而提供了极大的灵活性和扩展性。

相关文章:

【设计模式】工厂模式(创建型)⭐⭐⭐

文章目录 1.概念1.1 什么是工厂模式1.2 优点与缺点 2.实现方式2.1 简单工厂模式(Simple Factory)2.2 简单工厂模式缺点2.3 抽象工厂模式(Abstract Factory Pattern) 3 Java 哪些地方用到了工厂模式4 Spring 哪些地方用到了工厂模式…...

Postman 连接数据库 利用node+xmysql

1、准备nodejs环境 如果没有安装,在网上找教程,安装好后,在控制台输入命令查看版本,如下就成功了 2、安装xmysql 在控制台输入 npm install -g xmysql 3、连接目标数据库 帮助如下: 示例: 目标数据库…...

挑战你的数据结构技能:复习题来袭【6】

1. (单选题)设无向图的顶点个数为n,则该图最多有()条边 A. n-1 B. n(n-1)/2 C. n(n1)/2 D. 0 答案:B 分析: 2. (单选题)含有n个顶点的连通无向图,其边的个数至少为()。 A. n-1 B. n C. n1 D. nlog2n 答案:A…...

如何反编译jar并修改后还原为jar

如何反编译jar并修改后还原为jar 目标:修改jar包中某个类的某个方法后还原为新的jar 1.新建android工程,把旧的jar添加为lib 2.用jadx-gui打开旧的jar并保存所有资源 3.找到保存的资源中想修改的.java类 4.复制类中的内容, 在android工程中新建一个同样路径的包,并在包下创建…...

统计信号处理基础 习题解答10-5

题目 通过令 并进行计算来重新推导MMSE估计量。提示:利用结果 解答 首先需要明确的是: 上式是关于观测值x 的函数 其次需要说明一下这个结果 和教材一样,我们用求期望,需要注意的是,在贝叶斯情况下,是个…...

Vue3实战笔记(60)—从零开始:一步步搭建Vue 3自定义插件

文章目录 前言一、自定义插件二、使用步骤总结 前言 在开发和学习中,经常使用一些好用的插件,那么如何创建一个自己的插件呢?在 Vue 3 中,你可以通过创建一个包含 install 方法的对象来定义自定义插件。install 方法接收两个参数…...

Java面向对象笔记

多态 一种类型的变量可以引用多种实际类型的对象 如 package ooplearn;public class Test {public static void main(String[] args) {Animal[] animals new Animal[2];animals[0] new Dog();animals[1] new Cat();for (Animal animal : animals){animal.eat();}} }class …...

如何通过PHP语言实现远程控制多路照明

如何通过PHP语言实现远程控制多路照明呢? 本文描述了使用PHP语言调用HTTP接口,实现控制多路照明,通过多路控制器,可独立远程控制多路照明。 可选用产品:可根据实际场景需求,选择对应的规格 序号设备名称厂…...

Capture One Pro 23:专业 Raw 图像处理的卓越之选

在当今的数字摄影时代,拥有一款强大的图像处理软件至关重要。而 Capture One Pro 23 for Mac/Win 无疑是其中的佼佼者,为摄影师和图像爱好者带来了前所未有的体验。 Capture One Pro 23 以其出色的 Raw 图像处理能力而闻名。它能够精准地解析和处理各种…...

【主题广泛|投稿优惠】2024年交通运输与信息科学国际会议(ICTIS 2024)

2024年交通运输与信息科学国际会议(ICTIS 2024) 2024 International Conference on Transportation and Information Science 【重要信息】 大会地点:青岛 大会官网:http://www.icictis.com 投稿邮箱:icictissub-conf.…...

表格误删数据保存关闭后如何恢复?5个恢复方法大公开!

“我在编辑表格的时候一不小心就删除了部分数据,现在真的不知道该怎么操作了。希望大家能帮帮我吧!” 在日常工作中,我们经常会使用到各种表格软件来处理和分析数据。然而,有时由于操作失误或其他原因,我们可能会误删表…...

Go 语言中的切片:灵活的数据结构

切片(slice)是 Go 语言中一种非常重要且灵活的数据结构,它提供了对数组子序列的动态窗口。这使得切片在 Go 中的使用非常频繁,特别是在处理动态数据集时。本文将探讨切片的概念、操作和与函数的交互,以及如何有效地使用…...

在鲲鹏服务器搭建k8s高可用集群分享

高可用架构 本文采用kubeadm方式搭建k8s高可用集群,k8s高可用集群主要是对apiserver、etcd、controller-manager、scheduler做的高可用;高可用形式只要是为: 1. apiserver利用haproxykeepalived做的负载,多apiserver节点同时工作…...

MySQL之数据库事务机制学习笔记(五)

事务机制 事务(Transaction)是数据库管理系统中的一个重要概念,它是一组数据库操作的逻辑单元,要么全部执行成功,要么全部执行失败,具有以下四个特性,通常缩写为 ACID: 原子性&…...

linux 系统被异地登录,cpu占用拉满100%

一般是kswapd0导致的cpu占用异常 按顺序执行以下操作 在控制台执行top命令,查看占用最高的是否kswapd0。基本100%占用。记下该进程ID 5081 执行查找命令 find / -name kswapd0 显示查找结果: /proc/3316/.X2c4-unix/.rsync/a/kswapd0 /root/.configrc…...

智慧校园应用平台的全面建设

在当今社会,随着科技的不断进步,智慧校园应用平台逐渐成为学校管理的必备工具。在实现智慧校园全面建设的过程中,学校需要运用先进的技术和创新的理念,为教育提供更好的服务和支持。这篇文章将为您介绍智慧校园应用平台的全面建设…...

图论第6天

提高效率!!!两道题看并查集 841.钥匙和房间 忘了把visited 加引用了&#xff1a;& class Solution { public:bool canVisitAllRooms(vector<vector<int>>& rooms) {vector<int>visited(rooms.size(),false);dfs(rooms,visited,0);for(int i 0;i …...

Redis教程(二十一):Redis怎么保证缓存一致性

传送门:Redis教程汇总篇,让你从入门到精通 Redis 的缓存一致性 Redis 的缓存一致性是指在使用 Redis 作为缓存层时,保证缓存中的数据与数据库中的数据保持一致的状态。在分布式系统中,数据一致性是一个重要的问题,因为可能存在多个客户端同时读写同一数据,或者数据在不同…...

android apk签名

android apk签名 命令&#xff1a; java -jar signapk.jar platform.x509.pem platform.pk8 **.apk ***.apk note&#xff1a; apk密钥为&#xff1a; platform.pk8和platform.x509.pem 路径&#xff1a; build\target\product\security apk签名工具&#xff1a;sign…...

flutter 解析json另类封装方式 List<bean>,哈哈哈

flutter 解析json另类封装方式&#xff0c;哈哈哈 日常学习&#xff0c;仅供参考&#xff0c;不喜 勿喷 http请求数据泛型解析封装&#xff0c;需要判断泛型数据类型再根据类型解析&#xff0c;本文只抽取了list演示 核心代码 import dart:convert;import package:webwsyn/h…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...