设计模式之工厂模式(factory pattern):在商品对象创建系统中的应用
目录
一、设计思路
1. 简单工厂模式
2. 工厂方法模式
3. 抽象工厂模式
二、UML类图(PlantUML格式)
1.简单工厂模式
2.工厂方法模式
3.抽象工厂模式
三、实现过程与结果
1. 简单工厂模式
2. 工厂方法模式
3. 抽象工厂模式
四、总结
在面向对象设计中,工厂模式是一种常用的创建型设计模式,它通过将对象的创建逻辑集中管理,使得客户端无需直接创建对象,而是通过工厂类来获取所需的对象实例。这种设计思想不仅提高了代码的可扩展性和可维护性,还增强了系统的灵活性。本文将通过一个鼠标和键盘的商品对象创建系统,详细探讨简单工厂模式、工厂方法模式和抽象工厂模式的应用。
一、设计思路
1. 简单工厂模式
简单工厂模式通过一个统一的工厂类来创建对象,客户端通过传递类型参数来指定需要创建的对象。这种模式适合产品种类较少且不会频繁变化的场景。
-
鼠标接口:定义鼠标的基本行为。
-
具体鼠标类:实现无线鼠标和有线鼠标类,分别实现鼠标接口。
-
鼠标工厂类:根据传入的类型参数创建相应的鼠标对象。
2. 工厂方法模式
工厂方法模式通过定义一个抽象工厂接口,让具体的工厂类实现该接口来创建对象。客户端通过使用抽象工厂接口,而不直接调用具体工厂类。这种模式适合产品种类较多且可能频繁变化的场景。
-
鼠标接口:定义鼠标的基本行为。
-
具体鼠标类:实现无线鼠标和有线鼠标类。
-
抽象工厂接口:声明创建鼠标的方法。
-
具体工厂类:实现抽象工厂接口,分别创建无线鼠标和有线鼠标。
3. 抽象工厂模式
抽象工厂模式通过一个抽象工厂接口来创建多个相关的产品族。具体工厂实现该接口,生产一组相关的产品。这种模式适合需要创建多个相关产品族的场景。
-
鼠标接口:定义鼠标的基本行为。
-
键盘接口:定义键盘的基本行为。
-
具体产品类:实现无线鼠标、有线鼠标、无线键盘和有线键盘类。
-
抽象工厂接口:声明创建鼠标和键盘的方法。
-
具体工厂类:实现抽象工厂接口,分别创建无线设备(鼠标和键盘)和有线设备(鼠标和键盘)。
二、UML类图(PlantUML格式)
1.简单工厂模式
@startuml
interface Mouse {+ make()
}class WirelessMouse {+ make()
}class WiredMouse {+ make()
}class MouseFactory {+ createMouse(type: String): Mouse
}Mouse <|.. WirelessMouse
Mouse <|.. WiredMouse
MouseFactory --> Mouse
@enduml
2.工厂方法模式
@startuml
interface Mouse {+ make()
}class WirelessMouse {+ make()
}class WiredMouse {+ make()
}interface MouseFactory {+ createMouse(): Mouse
}class WirelessMouseFactory {+ createMouse(): Mouse
}class WiredMouseFactory {+ createMouse(): Mouse
}Mouse <|.. WirelessMouse
Mouse <|.. WiredMouse
MouseFactory <|.. WirelessMouseFactory
MouseFactory <|.. WiredMouseFactory
@enduml
3.抽象工厂模式
@startuml
interface Mouse {+ make()
}interface Keyboard {+ make()
}class WirelessMouse {+ make()
}class WiredMouse {+ make()
}class WirelessKeyboard {+ make()
}class WiredKeyboard {+ make()
}interface DeviceFactory {+ createMouse(): Mouse+ createKeyboard(): Keyboard
}class WirelessDeviceFactory {+ createMouse(): Mouse+ createKeyboard(): Keyboard
}class WiredDeviceFactory {+ createMouse(): Mouse+ createKeyboard(): Keyboard
}Mouse <|.. WirelessMouse
Mouse <|.. WiredMouse
Keyboard <|.. WirelessKeyboard
Keyboard <|.. WiredKeyboard
DeviceFactory <|.. WirelessDeviceFactory
DeviceFactory <|.. WiredDeviceFactory
@enduml
三、实现过程与结果
1. 简单工厂模式
代码实现:
public interface Mouse {void make();
}public class WirelessMouse implements Mouse {@Overridepublic void make() {System.out.println("制造无线鼠标");}
}public class WiredMouse implements Mouse {@Overridepublic void make() {System.out.println("制造有线鼠标");}
}public class MouseFactory {public Mouse createMouse(String type) {if ("wireless".equalsIgnoreCase(type)) {return new WirelessMouse();} else if ("wired".equalsIgnoreCase(type)) {return new WiredMouse();} else {return null;}}
}public class Demo {public static void main(String[] args) {MouseFactory factory = new MouseFactory();Mouse wirelessMouse = factory.createMouse("wireless");Mouse wiredMouse = factory.createMouse("wired");wirelessMouse.make(); // 输出:制造无线鼠标wiredMouse.make(); // 输出:制造有线鼠标}
}
2. 工厂方法模式
代码实现:
public interface Mouse {void make();
}public class WirelessMouse implements Mouse {@Overridepublic void make() {System.out.println("制造无线鼠标");}
}public class WiredMouse implements Mouse {@Overridepublic void make() {System.out.println("制造有线鼠标");}
}public interface MouseFactory {Mouse createMouse();
}public class WirelessMouseFactory implements MouseFactory {@Overridepublic Mouse createMouse() {return new WirelessMouse();}
}public class WiredMouseFactory implements MouseFactory {@Overridepublic Mouse createMouse() {return new WiredMouse();}
}public class Demo {public static void main(String[] args) {MouseFactory wirelessFactory = new WirelessMouseFactory();MouseFactory wiredFactory = new WiredMouseFactory();Mouse wirelessMouse = wirelessFactory.createMouse();Mouse wiredMouse = wiredFactory.createMouse();wirelessMouse.make(); // 输出:制造无线鼠标wiredMouse.make(); // 输出:制造有线鼠标}
}
3. 抽象工厂模式
代码实现:
public interface Mouse {void make();
}public interface Keyboard {void make();
}public class WirelessMouse implements Mouse {@Overridepublic void make() {System.out.println("制造无线鼠标");}
}public class WiredMouse implements Mouse {@Overridepublic void make() {System.out.println("制造有线鼠标");}
}public class WirelessKeyboard implements Keyboard {@Overridepublic void make() {System.out.println("制造无线键盘");}
}public class WiredKeyboard implements Keyboard {@Overridepublic void make() {System.out.println("制造有线键盘");}
}public interface DeviceFactory {Mouse createMouse();Keyboard createKeyboard();
}public class WirelessDeviceFactory implements DeviceFactory {@Overridepublic Mouse createMouse() {return new WirelessMouse();}@Overridepublic Keyboard createKeyboard() {return new WirelessKeyboard();}
}public class WiredDeviceFactory implements DeviceFactory {@Overridepublic Mouse createMouse() {return new WiredMouse();}@Overridepublic Keyboard createKeyboard() {return new WiredKeyboard();}
}public class Demo {public static void main(String[] args) {DeviceFactory wirelessFactory = new WirelessDeviceFactory();DeviceFactory wiredFactory = new WiredDeviceFactory();Mouse wirelessMouse = wirelessFactory.createMouse();Keyboard wirelessKeyboard = wirelessFactory.createKeyboard();Mouse wiredMouse = wiredFactory.createMouse();Keyboard wiredKeyboard = wiredFactory.createKeyboard();wirelessMouse.make(); // 输出:制造无线鼠标wirelessKeyboard.make(); // 输出:制造无线键盘wiredMouse.make(); // 输出:制造有线鼠标wiredKeyboard.make(); // 输出:制造有线键盘}
}
四、总结
工厂模式的三种主要形式及其适用场景。每种模式都有其独特的优点和适用范围,合理选择和应用这些模式可以显著提升软件设计的质量和效率。
-
简单工厂模式:简单工厂模式以其简洁性和易于理解的特点,非常适合产品种类较少且相对稳定的场景。它通过一个统一的工厂类集中管理对象的创建逻辑,使得客户端代码更加简洁。然而,随着产品种类的增加,简单工厂类的条件判断逻辑可能会变得复杂,这可能会降低代码的可维护性。
-
工厂方法模式:工厂方法模式通过将对象的创建逻辑分散到多个具体的工厂类中,有效地解决了简单工厂模式在面对产品种类频繁变化时的扩展性问题。每个具体工厂类负责创建一种具体的产品,这使得系统在添加新产品时更加灵活,只需新增相应的工厂类而无需修改现有代码。这种模式特别适合产品种类较多且可能频繁变化的场景,它不仅提高了代码的可扩展性,还符合开闭原则,即对扩展开放,对修改关闭。
-
抽象工厂模式:抽象工厂模式在处理多个相关产品族的创建时表现出色。它通过一个抽象工厂接口定义了一组创建相关产品的方法,具体工厂实现这些方法来生产特定产品族中的产品。这种模式使得系统能够在不依赖具体产品实现的情况下,灵活地切换不同的产品族。这对于需要支持多种产品组合的系统来说是一个巨大的优势,它不仅提高了代码的可维护性,还增强了系统的灵活性和可扩展性。
在实际的软件开发中,选择合适的工厂模式需要综合考虑系统的复杂性、产品的种类和变化频率以及系统的扩展需求。简单工厂模式适合小型项目或产品种类较少的场景;工厂方法模式适用于产品种类较多且可能频繁变化的系统;而抽象工厂模式则更适合需要创建多个相关产品族的复杂系统。
此外,工厂模式的应用还体现了面向对象设计的核心原则,如封装、多态和依赖倒置等。通过将对象的创建逻辑封装在工厂类中,客户端代码可以依赖于抽象而非具体实现,这使得系统更加灵活,能够更好地应对需求的变化。
总之,工厂模式作为一种经典的创建型设计模式,为对象的创建提供了一种优雅的解决方案。它不仅能够提高代码的可读性和可维护性,还能够增强系统的扩展性和灵活性。在未来的软件设计中,合理运用工厂模式将有助于我们构建出更加健壮、灵活和易于维护的软件系统。
相关文章:
设计模式之工厂模式(factory pattern):在商品对象创建系统中的应用
目录 一、设计思路 1. 简单工厂模式 2. 工厂方法模式 3. 抽象工厂模式 二、UML类图(PlantUML格式) 1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式 三、实现过程与结果 1. 简单工厂模式 2. 工厂方法模式 3. 抽象工厂模式 四、总结 在面向对…...
Spring Boot 自定义定时任务组件深度解析:Quartz 集成与设计模式实战
一、组件设计目标 解决痛点: 简化 Quartz 原生 API 的复杂性统一任务调度管理(增删改查、日志、重试)与 Spring Boot 生态无缝整合 二、实现步骤详解 1. 组件初始化配置 1.1 初始化 Quartz 表结构 下载 SQL 脚本 🔗 官方表…...
嵌入式exfat-nofuse文件系统移植和使用
exfat-nofuse 是一款专为linux ARM平台设计的开源项目,它提供了一个非FUSE机制的内核级驱动,用于在Linux系统上无缝地读写exFAT和VFAT文件系统。此项目由Dorimanx维护,采用C语言编写,兼容GPL-2.0许可证。它避开了FUSE(用户空间文件系统)的使用…...
再来一篇,Linux中的软件管理
Linux中软件包的类型 在Linux系统中,软件包有多种不同的格式和类型,主要包括以下几种: DEB (Debian软件包)(此软件包不适用于RHEL8 系统): 适用于 Debian 及其衍生版本(如Ubuntu等&…...
【重学Android】02.Java环境配置的一些分享
背景说明 其实只是学习Android的话,只要下载好Android Studio开发工具,是自带JDK环境的,所以不需要再额外去进行配置,我之所以还要进行单独配置,是因为我其他的工具需要Java的环境,而且我目前用的是JDK 12…...
SimBody安装
SimBody安装 Simbody 是一个用于创建生物力学和机械系统仿真的多体动力学库。 SimBody安装 Windows安装: 下载地址:GitHub - simbody/simbody: High-performance C multibody dynamics/physics library for simulating articulated biomechanical and…...
CUDA编程中影响性能的小细节总结
一、内存访问优化 合并内存访问:确保相邻线程访问连续内存地址(全局内存对齐访问)。优先使用共享内存(Shared Memory)减少全局内存访问。避免共享内存的Bank Conflict(例如,使用padding或调整访…...
thinkphp:部署完整项目到本地phpstudy
一、准备工作 首先准备一个thinkphp的项目文件;准备mysql数据库 二、小皮初步搭建 1、建立网站 在小皮界面,网站->创建网站->输入域名,选择PHP版本等 注:确保端口未被占用 2、将项目文件放入根目录 网站->管理->…...
Linux网络编程——基于ET模式下的Reactor
一、前言 上篇文章中我们已经讲解了多路转接剩下的两个接口:poll和epoll,并且知道了epoll的两种工作模式分别是 LT模式和ET模式,下来我们就实现的是一个简洁版的 Reactor,即半同步半异步I/O,在linux网络中,…...
大模型相关面试问题原理及举例
大模型相关面试问题原理及举例 目录 大模型相关面试问题原理及举例Transformer相关面试问题原理及举例大模型模型结构相关面试问题原理及举例注意力机制相关面试问题原理及举例大模型与传统模型区别 原理:大模型靠海量参数和复杂结构,能学习更复杂模式。传统模型参数少、结构…...
Redis List 的详细介绍
Redis List 的详细介绍 以下是 Redis List 的详细介绍,从基础命令、内部编码和使用场景三个维度展开: 一、基础命令 Redis List 支持双向操作(头尾插入/删除),适用于队列、栈等场景,以下是核心命令分类&a…...
使用virtualbox的HostOnly建立共享网络-实现虚拟机上网
目录 环境描述解决方案具体步骤1.新建一个virtual host-only ethernet adapter2.设置windows的wifi信号网络共享3.确认winows宿主网络信息3.1.wifi适配器的信息3.2.虚拟网卡的信息3.3.确认virtualbox中虚拟网卡的ip地址 4.虚拟机网卡设置5.虚拟机网络设置5.1.本地连接设置5.2.u…...
springboot+vue3+mysql+websocket实现的即时通讯软件
项目演示 即时通讯软件项目演示 业务架构 技术栈 后端 选用编程语言 Javaweb框架SpringBootdb MySQL 持久存储nosql 缓存 Redis全双工通信框架 WebSocket 前端 前端框架Vue3TypescriptUI样式 Css、ElementPlus网页路由 vue-router全双工通信框架Websocket 功能完成情况 已实…...
基于 Spring Boot 瑞吉外卖系统开发(五)
基于 Spring Boot 瑞吉外卖系统开发(五) 删除分类 分类列表中每条分类信息右侧提供了一个“删除”按钮,当需要将已经存在的分类信息删除时,可以通过单击“删除”按钮实现。 请求路径为/category,携带参数id…...
AES (高级加密标准)
原理详解 AES是一种对称加密算法,使用相同的密钥进行加密和解密。它采用替代-置换网络(SPN)结构,主要步骤包括: 密钥扩展:从初始密钥派生多轮密钥 初始轮:AddRoundKey(轮密钥加) 主轮ÿ…...
详解Windows(一)——系统盘下目录及文件详解
引言 你是否曾经好奇过电脑里那些神秘的文件夹都是干什么用的?为什么有些文件是.exe而有些是.dll?不同的图片格式.jpg和.png到底有什么区别?如果你对这些问题感到困惑,这篇文章就是为你准备的。今天,我们将以通俗易懂…...
基于Spring MVC的客户端真实IP获取方案解析
文章目录 基于Spring MVC的客户端真实IP获取方案解析概述核心方法解析代码实现工作流程 IP获取优先级策略IP有效性验证异常处理与日志使用场景注意事项扩展建议 基于Spring MVC的客户端真实IP获取方案解析 概述 在Web应用开发中,准确获取客户端真实IP地址是常见的…...
【Web部署问题】在Tomcat中部署web项目出现http状态-404 -未找到详细解决方案
部署完tomcat记得在选中要运行的工件。 如果没有工件,或者工件有缺失东西,去这里配置工件,...
Linux——Shell编程之正则表达式与文本处理器(笔记)
目录 基础正则表达式 1:基础正则表达式示例 (4)查找任意一个字符“.”与重新字符“*” (5)查找连续字符范围“{ }” 文本处理器 一、sed工具 二、awk工具 (1)按行输出文本 (2࿰…...
Linux 进程控制(自用)
非阻塞调用waitpid 这样父进程就不会阻塞,此时循环使用我们可以让父进程执行其他任务而不是阻塞等待 进程程序替换 进程PCB加载到内存中的代码和数据 替换就是完全替换当前进程的代码段、数据段、堆和栈,保存当前的PCB 代码指的是二进制代码不是源码&a…...
05-DevOps-Jenkins自动拉取构建代码
新建Gitlab仓库 先在Gitab上创建一个代码仓库,选择创建空白项目 安装说明进行填写,然后点击创建项目 创建好的仓库是空的,什么都没有 新建一个springboot项目,用于代码上传使用。 只是为了测试代码上传功能,所以代码…...
【Spring学习】
Spring学习 简介 Spring 是一个开源的 Java 企业级开发框架,最核心的特点是: IOC(控制反转)AOP(面向切面编程) 它有完整的生态: 🚀 Spring Boot:用于快速构建服务&a…...
网络基础与 HTTP 协议
一、网络基础 (一)TCP/IP 协议族 TCP/IP 协议族是互联网通信的核心协议,它包含了多个层次的协议,共同协作实现网络通信。 1. IP 协议 IP(Internet Protocol)协议位于网络层,主要负责将数据包…...
SRS transcode支持 h264_nvenc 硬件解码方案
文章目录 SRS transcode支持 h264_nvenc 硬件解码方案1、修改文件2、重新编译3、使用 SRS transcode支持 h264_nvenc 硬件解码方案 SRS 是开源的流媒体服务,但在使用 GPU 服务器时,想要通过硬件加速,目前官方是不支持的,所以简单…...
阿里云服务器搭建开源版禅道
一,下载地址:禅道11.5版本发布,主要完善细节,修复bug,新增动态过滤机制 - 禅道下载 - 禅道项目管理软件 下载地址二: 禅道21.6.stable 实现旧编辑器撰写的文档无感升级至新版编辑器 - 禅道下载 - 禅道项目…...
【刷题Day21】TCP(浅)
说说 TCP 的四次挥手? TCP的四次挥手事用于安全关闭一个已建立的连接的过程,它确保双方都能完成数据传输并安全地释放连接资源。 简述步骤: 第一次挥手(FIN --> ACK):客户端主动关闭连接,…...
怎么用面向对象和状态机架构,设计一个通用的按键检测功能?
说起按键检测,在座的各位,哪个没被它折磨过? 我刚入门时,为了实现一个简单的按键功能,硬生生写了几十行代码,各种 if...else 嵌套,逻辑绕得我自己都头晕。 更可气的是,辛辛苦苦写完…...
Java基础系列-LinkedList源码解析
文章目录 简介LinkedList 插入和删除元素的时间复杂度?LinkedList 为什么不能实现 RandomAccess 接口? LinkedList 源码分析Node 定义初始化获取元素插入元素删除元素遍历链表 简介 LinkedList 是一个基于双向链表实现的集合类,经常被拿来和…...
day47—双指针-平方数之和(LeetCode-633)
题目描述 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 b^2 c 。 示例 1: 输入:c 5 输出:true 解释:1 * 1 2 * 2 5示例 2: 输入:c 3 输出:f…...
qwen 14B模型配置文件,层名称weight_map. 28GB
qwen 14B模型配置文件,层名称weight_map. 28GB 目录 qwen 14B模型配置文件,层名称weight_map. 28GBmetadata(元数据)weight_map(权重映射)lm_head.weightmodel.layersmlp.{proj_type}.weightpost_attention_layernormself_attn.{proj_type}.{bias_or_weight}model.norm.w…...
