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

【设计模式】工厂模式详解

1.简介

工厂模式是一种创建型设计模式,通过提供一个接口或抽象类来创建对象,而不是直接实例化对象。工厂模式的主要思想是将对象的创建与使用分离,使得创建对象的过程更加灵活和可扩展。

工厂模式主要包括以下角色:

  • 抽象工厂(Abstract Factory):定义了一个创建产品对象的接口,可以包含多个方法来创建不同类型的产品。
  • 具体工厂(Concrete Factory):实现抽象工厂接口,负责实例化具体的产品对象。
  • 抽象产品(Abstract Product):定义了产品的接口或抽象类,是工厂方法和抽象工厂模式中的基础。
  • 具体产品(Concrete Product):实现抽象产品接口,具体定义产品的功能和行为。

2.简单工厂模式

简单工厂模式(Simple Factory Pattern):由一个工厂类根据传入的参数决定创建哪一种产品类的实例。它通常包含一个静态方法,这个方法根据参数创建相应的对象。

定义一个简单的例子:电脑有很多品牌,如惠普电脑、联想电脑,如果需要创建这两个对象时,主动new出来,使用了简单工厂模式后,可以把创建的动作交给工厂类,只需要指定参数即可获取对应的对象。

实现方法

  1. 编写产品类

首先创建一个Computer接口,不同的产品实现这一接口

// 定义抽象产品接口
public interface Computer {void compute();
}// 定义具体产品,实现该接口
public class HPComputer implements Computer{@Overridepublic void compute() {System.out.println("我是惠普电脑");}
}public class LenovoComputer implements Computer{@Overridepublic void compute() {System.out.println("我是联想电脑");}
}
  1. 编写工厂类

简单工厂模式不存在抽象工厂,只需编写一个工厂类即可。

// 根据传入的参数创建对应产品
public class SimpleFactory {public static Computer createProduct(String type) {if (type.equals("HP")) {return new HPComputer();} else if (type.equals("Lenovo")) {return new LenovoComputer();} else {throw new IllegalArgumentException("该类型无法被生产");}}
}
  1. 测试类使用工厂创建产品
public class Main {public static void main(String[] args) {// 创建HP电脑Computer hp = SimpleFactory.createProduct("HP");// 创建Lenovo电脑Computer lenovo = SimpleFactory.createProduct("Lenovo");hp.compute();lenovo.compute();}
}

输出结果如下:

小结

简单工厂模式虽然实现比较简单,但是工厂类的职责过重,增加新的产品类型需要修改工厂类,违背了开闭原则。

开闭原则: 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。

对扩展开放(Open for extension):软件实体应该允许在不改变其现有代码的情况下,通过增加新功能来对其进行扩展。也就是说,当软件的需求发生变化时,我们应该能够通过添加新代码来满足这些需求,而不需要修改已有的代码。

对修改关闭(Closed for modification):一旦软件实体被开发完成并投入使用,其源代码就不应该再被修改。这可以防止对现有功能的破坏,减少引入新的错误的风险,并使软件更加稳定和可维护。

3.工厂方法模式

工厂方法模式(Factory Method Pattern):定义一个创建对象的接口,但由子类决定实例化哪个类。工厂方法将对象的创建推迟到子类。

实现方法

  1. 编写产品类
// 定义抽象产品接口
public interface Computer {void compute();
}// 定义具体产品,实现该接口
public class HPComputer implements Computer{@Overridepublic void compute() {System.out.println("我是惠普电脑");}
}public class LenovoComputer implements Computer{@Overridepublic void compute() {System.out.println("我是联想电脑");}
}
  1. 编写工厂类

需要定义一个抽象工厂,然后由具体工厂创建对应的产品。

// 定义抽象工厂
public interface ComputerFactory {Computer createComputer();
}// 定义HP工厂
public class HPComputerFactory implements ComputerFactory{@Overridepublic Computer createComputer() {return new HPComputer();}
}// 定义Lenovo工厂
public class LenovoComputerFactory implements ComputerFactory{@Overridepublic Computer createComputer() {return new LenovoComputer();}
}
  1. 测试类使用不同的具体工厂创建产品
public class Main {public static void main(String[] args) {// 创建HP电脑HPComputerFactory hpFactory = new HPComputerFactory();Computer hpComputer = hpFactory.createComputer();hpComputer.compute();// 创建Lenovo电脑LenovoComputerFactory lenovoFactory = new LenovoComputerFactory();Computer lenovoComputer = lenovoFactory.createComputer();lenovoComputer.compute();}
}

输出结果如下:

小结

优点:

  • 遵循开闭原则,新增产品时不需要修改现有系统代码,只需要添加新的具体工厂和具体产品类。
  • 更符合单一职责原则,每个具体工厂类只负责创建一种产品。

缺点:

  • 增加了系统复杂度,需要增加额外的类和接口。

4.抽象工厂模式

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。适用于产品族的场景,即多个产品等级结构中相关的产品需要一起创建和使用。

产品等级结构: 指产品的继承结构,例如一个电脑抽象类,它有HP电脑、Lenovo电脑等实现类,那么这个电脑抽象类和他的实现类就构成了一个产品等级结构。

产品族: 产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,Lenovo除了生产电脑还可以生产打印机等其他产品。

实现方法

  1. 编写产品类
// 定义电脑抽象产品接口
public interface Computer {void compute();
}// 定义电脑具体产品,实现该接口
public class HPComputer implements Computer{@Overridepublic void compute() {System.out.println("我是惠普电脑");}
}public class LenovoComputer implements Computer{@Overridepublic void compute() {System.out.println("我是联想电脑");}
}// 定义打印机抽象产品接口
public interface Printer {void print();
}// 定义打印机具体产品,实现该接口
public class HPPrinter implements Printer {@Overridepublic void print() {System.out.println("我是惠普打印机");}
}public class LenovoPrinter implements Printer{@Overridepublic void print() {System.out.println("我是联想打印机");}
}
  1. 编写工厂类

定义一个抽象工厂,该工厂可以创建多个产品。

// 定义抽象工厂
public interface AbstractFactory {Computer createComputer();Printer createPrinter();
}// 定义HP工厂
public class HPFactory implements AbstractFactory{@Overridepublic Computer createComputer() {return new HPComputer();}@Overridepublic Printer createPrinter() {return new HPPrinter();}
}// 定义Lenovo工厂
public class LenovoFactory implements AbstractFactory {@Overridepublic Computer createComputer() {return new LenovoComputer();}@Overridepublic Printer createPrinter() {return new LenovoPrinter();}
}
  1. 测试类使用不同的具体工厂创建产品
public class Main {public static void main(String[] args) {HPFactory hpFactory = new HPFactory();Computer hpComputer = hpFactory.createComputer();Printer hpPrinter = hpFactory.createPrinter();hpComputer.compute();hpPrinter.print();System.out.println("===============");LenovoFactory lenovoFactory = new LenovoFactory();Computer lenovoComputer = lenovoFactory.createComputer();Printer lenovoPrinter = lenovoFactory.createPrinter();lenovoComputer.compute();lenovoPrinter.print();}
}

输出结果如下:

小结

优点:

  • 符合开闭原则,新增产品族时无需修改现有系统代码。
  • 符合单一职责原则,每个具体工厂类只负责创建一类产品族。
  • 保证产品族的一致性,同一个工厂创建的产品是属于同一个产品族的。

缺点:

  • 增加了系统的复杂度。修改产品族时,需要修改所有具体工厂类,扩展性稍差。

5.总结

适用场景:

  • 简单工厂模式:适用于产品种类较少,客户端只需根据参数获得具体产品的简单场景。适合产品种类不经常变化的场合。

  • 工厂方法模式:适用于产品种类较多,每个产品有相应的具体工厂类。适合需要扩展新产品,且不希望修改现有代码的场合。

  • 抽象工厂模式:适用于产品族较多,每个产品族中包含多个相关产品。适合创建一系列相关或相互依赖的产品,且希望统一管理产品族的场合。

相关文章:

【设计模式】工厂模式详解

1.简介 工厂模式是一种创建型设计模式,通过提供一个接口或抽象类来创建对象,而不是直接实例化对象。工厂模式的主要思想是将对象的创建与使用分离,使得创建对象的过程更加灵活和可扩展。 工厂模式主要包括以下角色: 抽象工厂&a…...

【Spring Boot】用 Spring Security 实现后台登录及权限认证功能

用 Spring Security 实现后台登录及权限认证功能 1.引入依赖2.创建权限开放的页面3.创建需要权限验证的页面4.配置 Spring Security4.1 配置 Spring MVC4.2 配置 Spring Security 5.创建登录页面6.测试权限 1.引入依赖 使用前需要引入相关依赖,见以下代码&#xff…...

PHP开发【石头剪刀布小游戏】

石头剪刀布小游戏 玩法超级简单,你只需要在下面选择石头、剪刀或者布,然后提交,系统就会随机生成电脑的选择,告诉你最终的结果哦! 游戏规则: 如果你的选择和电脑一样,那么就是平局。如果你赢…...

(leetcode学习)42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…...

Python编程实例2

一、通过用户输入数字计算阶乘 # 获取用户输入的数字 num int(input("请输入一个数字: ")) factorial 1 # 查看数字是负数&#xff0c;0 或 正数 if num < 0:print("抱歉&#xff0c;负数没有阶乘") elif num 0:print("0 的阶乘为 1") e…...

排序算法:堆排序,golang实现

目录 前言 堆排序 代码示例 1. 算法包 2. 堆排序代码 3. 模拟程序 4. 运行程序 5. 从大到小排序 堆排序的思想 堆排序的实现逻辑 1. 构建最大堆 2. 排序 循环次数测试 假如 10 条数据进行排序 假如 20 条数据进行排序 假如 30 条数据进行排序 假设 5000 条数据…...

【网络安全入门】学习网络安全必须知道的77个网络基础知识

1、TCP/IP 协议的四层模型&#xff08;网络接口层、网络层、传输层、应用层&#xff09; TCP/IP 协议是互联网通信的基础&#xff0c;四层模型中&#xff0c;网络接口层负责与物理网络的连接&#xff1b;网络层主要处理 IP 数据包的路由和转发&#xff1b;传输层提供端到端的可…...

limit 以及分页 SQL 语句

目录 1. 作用 2. 演示 3. 分页 SQL 语句 1. 作用 获取结果集的一部分&#xff1b; 2. 演示 &#xff08;1&#xff09;如下&#xff0c;获取表的前三行&#xff1b; &#xff08;2&#xff09;只有一个数字&#xff0c;默认从 0 开始&#xff1b; &#xff08;3&#x…...

mysql8.0规范

MySQL 数据库开发规范 目录 背景与目标规范列表 1. 库表设计 1.1 必须字段1.2 命名规范 2. 定义规范 2.1 约束规范2.2 类型规范 2.2.1 字段类型与长度2.2.2 状态字段数据类型2.2.3 布尔型2.2.4 varchar和text, json2.2.5 decimal(m,d) 3. 索引规范4. 其他规范5. SQL 使用 5.…...

现代前端架构介绍(第三部分):深入了解状态管理层及其对前端App的影响

远离JavaScript疲劳和框架大战&#xff0c;了解真正重要的东西 在第二部分中&#xff0c;我们讨论了功能架构的三个层次。其中一个就是状态管理层&#xff0c;今天我们将对其进行更深入的探讨。下面是现代前端架构系列的第三部分和最后一部分介绍。 状态管理&#xff0c;你可能…...

NLP与搜广推常见面试问题

1 auc指标 AUC的两种意义 一个是ROC曲线的面积另外一个是统计意义。从统计学角度理解&#xff0c;AUC等于随机挑选一个正样本和负样本时&#xff0c;模型对正样本的预测分数大于负样本的预测分数的概率。下图为搜广推场景下的一个计算auc的例子 2 GAUC指标 就是在推荐系统…...

Python怎么实现协程并发呢?

在Python中&#xff0c;实现协程并发主要是通过asyncio库来完成的。asyncio是Python 3.4中引入的标准库&#xff0c;用于编写单线程的并发代码。使用async和await关键字&#xff0c;你可以定义协程和等待其他协程的完成&#xff0c;而不需要创建额外的线程或进程。 下面是一个使…...

专治408开始的晚!8月一定要完成这些事!

八月份才开始408&#xff0c;那到考试最多也只有4-5个月的时间 别担心&#xff0c;可以复习两轮&#xff01; 其实我一直建议大家408复习三轮&#xff0c;但是如果时间不够&#xff0c;那就要在复习质量上下功夫&#xff01; 考408有一个好处&#xff0c;就是不用先确定学校…...

计算机毕业设计选题推荐-校内跑腿业务系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

Unity命名验证工具类

在Unity开发中&#xff0c;经常需要验证变量名是否符合命名规范&#xff0c;同时避免使用C#的保留字作为变量名。本教程将演示如何创建一个简单的工具类来实现这一功能。 步骤 1&#xff1a;创建Unity命名验证工具类 首先&#xff0c;我们创建一个C#类&#xff0c;命名为Unit…...

基于cubeMX的STM32开启SPI及DMA

1、打开cubeMX后&#xff0c;设置SPI&#xff0c;如下图 2、设置SPI的DMA中断 3、DMA设置 4、SPI的GPIO设置 5、最后生成代码&#xff0c;可以看到工程文件中有dma.c和spi.c 6、使用举例&#xff1a;如幻彩灯的亮灭使用SPIDMA产生的信号波形来控制&#xff0c;在ws2812.c中调用…...

AI大模型技术的四大核心架构分析

AI大模型技术的四大核心架构演进之路 随着人工智能技术的飞速发展&#xff0c;大模型技术已经成为AI领域的重要分支。 深度剖析四大大模型技术架构&#xff1a;纯粹的Prompt提示词法、Agent Function Calling机制&#xff0c;RAG&#xff08;检索增强生成&#xff09;及Fine-…...

[C#]调用本地摄像头录制视频并保存

AForge.NET是一个基于C#框架设计的开源计算机视觉和人工智能库&#xff0c;专为开发者和研究者设计。它提供了丰富的图像处理和视频处理算法、机器学习和神经网络模型&#xff0c;具有高效、易用、稳定等特点。AForge库由多个组件模块组成&#xff0c;包括AForge.Imaging&#…...

opencv-图像基础变换

1&#xff0c;缩放 缩放是对图像的大小进行调整 缩放矩阵&#xff0c;相当于x和y乘一个常数 例如将图像放大两倍 import cv2 img cv2.imread(1.jpg) img cv2.resize(img, (400,400)) img cv2.resize(img, (0,0), fx3, fy1)#表示x方向扩大三倍&#xff0c;y方向不变 2&…...

xss漏洞(三,xss进阶利用)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 前言&#xff1a; 1&#xff0c;本文基于dvwa靶场以及PHP study进行操作&#xff0c;靶场具体搭建参考上一篇&#xff1a; xss漏洞&#xff08;二&#xff0c;xss靶场搭建以及简单…...

git 迁移仓库的方法

git Git是一个开源的分布式版本控制系统&#xff0c;由Linus Torvalds在2005年创建&#xff0c;用于有效、高速地处理从小到大的项目管理。它最初是为Linux内核开发而设计的&#xff0c;但很快被广泛用于各种项目。 以下是Git的一些主要特性&#xff1a; 分布式架构&#xff…...

C# Where关键字

1. 泛型约束&#xff08;Generic Constraints&#xff09; 在泛型类、接口或方法的定义中&#xff0c;where关键字用于指定类型参数的约束。这些约束可以确保类型参数具有某些特定的属性。例如它是一个类、实现了某个接口、是另一个类型的派生类、具有无参构造函数等。 1.1 …...

《计算机组成原理》(第3版)第1章 计算机系统概论 复习笔记

第1章 计算机系统概论 一、计算机系统简介 &#xff08;一&#xff09;计算机的软硬件概念 1&#xff0e;计算机系统由“硬件”和“软件”两大部分组成 &#xff08;1&#xff09;所谓“硬件”&#xff0c;是指计算机的实体部分&#xff0c;如主机、外部设备等。 &#xff0…...

达梦数据库的系统视图v$cachers

达梦数据库的系统视图v$cachers 达梦数据库的系统视图V$CACHERS的作用是显示缓存中的项信息&#xff0c;在 ini 参数 USE_PLN_POOL !0 时才统计。这个视图帮助数据库管理员监控和分析缓存的使用情况&#xff0c;优化数据库性能。通过查询V$CACHERS视图&#xff0c;可以获取缓存…...

电路元件基本知识详解

电路元件基本知识详解 在现代电子技术中&#xff0c;电路元件是构成各种电子电路的基本单元。它们各自具有不同的特性和功能&#xff0c;通过不同的连接方式实现多种多样的电路功能。本文将详细介绍几种常见的电路元件及其基本知识。 ### 一、电阻器 #### 1. 电阻器的基本概…...

从零开始写一个微信小程序

从零开始写一个微信小程序可以分为几个步骤。以下是一个详细的指南,帮助你从头到尾完成一个简单的微信小程序。 ### 一、准备工作 1. **注册微信小程序账号**: - 前往[微信公众平台](https://mp.weixin.qq.com/)注册一个小程序账号。 - 进行企业认证(个人账号需要申…...

07030405复杂可编程逻辑器件CPLD现场可编程阵列FPGA

复杂可编程逻辑器件CPLD&现场可编程阵列FPGA 7.3 复杂可编程逻辑器件CPLD7.3.1CPLD的结构 7.4现场可编程门阵列FPGA7.4.1FPGA实现逻辑功能的基本原理7.4.2FPGA结构简介1.可编程逻辑块2.I/O块3.可编程连线资源CPLD与FPGA的区别 7.5可编程逻辑器件开发过程简介编程条件 7.3 复…...

《雅思口语真经总纲1.0》话题实战训练笔记part1——5. Bus or taxi

《雅思口语真经总纲1.0》笔记——第四章&#xff1a;口语素材大全&#xff08;part1、part2、part3回答准则及练习方法&#xff0c;不包括范例答案&#xff09;★★★★★ 文章目录 Bus or taxiHou often do you take the bus?20240803答评价疑问 When was the first time you…...

《工程检索增强生成系统时的七个失败点》论文 AI 解读

周末使用 AI 速度了一篇 RAG 相关的论文&#xff0c;文中提到的【设计 RAG 系统时需要考虑的七个失败点】非常有价值&#xff0c;简单整理一下分享出来&#xff0c;大家如果感兴趣可以继续阅读原文。 论文名称&#xff1a;Seven Failure Points When Engineering a Retrieval A…...

每日一题——贪心算法

1005. K 次取反后最大化的数组和 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a; 一开始有点理解错他的意思&#xff0c;以为是i是题目中会给出&#xff0c;所以一开始没有什么思路&#xff0c;然后当看了题解之后&#xff0c;就知道了原来i是自己订的&#xff0c…...

中国手机最好的网站排名/谷歌搜索引擎363

这是mysql系列第2篇文章。 环境&#xff1a;mysql5.7.25&#xff0c;cmd命令中进行演示。 主要内容 介绍mysql中常用的数据类型 mysql类型和java类型对应关系 数据类型选择的一些建议 MySQL的数据类型 主要包括以下五大类 整数类型&#xff1a;bit、bool、tinyint、smallint、…...

广州真的要放开了/seo技术有哪些

为什么80%的码农都做不了架构师&#xff1f;>>> #编者注 由于CentOS源当中默认没有MySQL服务&#xff0c;则需要去网络上进行下载并安装 #MySQL官网 MySQL官网MySQL Community下载页面 可以在该页面查看到有YUM与APT的安装源&#xff0c;则我们需要下载安装源&…...

深圳网站建设 cms/合肥百度搜索排名优化

適度に運動したほうが勉強は、捗る。このことは、誰でも経験的に感じていると思いますが、医学的にも裏づけがあります。勉強をしているときに使っているのは、脳全体のうち、ほんのごくわずかに過ぎません。とかく頭脳は考えるための臓器だと思われがちですが、こうした知的な…...

企业网站备案信息/微信软文怎么写

本文是 重温基础 系列文章的第五篇。 今日感受&#xff1a;家的意义。本章节复习的是JS中的表达式和运算符&#xff0c;用好这些可以大大提高开发效率。 一些基础&#xff1a;JavaScript中运算符有一元、二元和三元&#xff08;条件&#xff09;运算符&#xff0c;常见写法&…...

专业做家电的网站/腾讯广告推广怎么做

点击关注公众号&#xff0c;实用技术文章及时了解功能说明nginxWebUI是一款图形化管理nginx配置的工具&#xff0c;可以使用网页来快速配置nginx的各项功能&#xff0c;包括http协议转发、tcp协议转发、反向代理、负载均衡、静态html服务器、ssl证书自动申请、续签、配置等。配…...

凯里网站建设流程/地推团队如何收费

中国纳米锌行业发展策略及投资建议研究报告2022-2028年 ═━┈┈━══━┈┈━══━┈┈━══━ 【出版机构】: 中商经济研究网 第一章 2017-2021年中国纳米锌行业发展分析 第一节 纳米锌行业发展现状 一、纳米锌行业概念 二、纳米锌行业主要产品分类 三、纳米锌行…...