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

设计模式-创建型-工厂方法模式

什么是工厂方法模式?

工厂方法模式(Factory Method Pattern)是 创建型设计模式之一,目的是通过定义一个用于创建对象的接口,让子类决定实例化哪个类。简而言之,工厂方法模式通过延迟对象的创建过程到子类来减少代码耦合,使得代码更加灵活且易于扩展。

工厂方法模式的核心思想

  • 工厂方法模式通过将对象的创建过程交给子类来实现解耦,这使得代码更加灵活,能够应对需求变化时的扩展。
  • 客户端不需要知道具体的类名,只需要通过工厂方法获取所需的对象。
  • 它是“简单工厂模式”的扩展,解决了简单工厂模式中单一工厂类引起的复杂性问题。

主要组成部分

工厂方法模式的实现通常包括以下几个关键组件:

  1. 产品(Product):定义产品的接口,所有具体的产品类都实现该接口。
  2. 具体产品(ConcreteProduct):实现产品接口的具体类,代表某种具体的产品。
  3. 工厂方法(Creator):声明工厂方法,返回一个产品对象。通常它是一个抽象类或接口。
  4. 具体工厂(ConcreteCreator):实现工厂方法,返回具体的产品对象。

工厂方法模式的代码实现

为了帮助大家理解工厂方法模式,下面我们通过一个具体的例子来实现它。假设我们正在开发一个图形绘制应用,支持不同类型的图形(如圆形和方形)。我们将通过工厂方法来创建不同的图形对象。

1. 定义产品接口

首先,我们定义一个 Shape 接口,所有的具体图形类(如 CircleSquare)都需要实现这个接口。

from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef draw(self):pass

2. 创建具体产品类

接下来,我们创建两个具体的产品类,CircleSquare,它们分别实现 Shape 接口。

class Circle(Shape):def draw(self):print("Drawing a Circle!")class Square(Shape):def draw(self):print("Drawing a Square!")

3. 定义工厂方法接口

然后,我们定义一个 ShapeFactory 接口,声明一个 create_shape 方法,返回一个 Shape 对象。

class ShapeFactory(ABC):@abstractmethoddef create_shape(self) -> Shape:pass

4. 创建具体工厂类

接下来,我们创建两个具体工厂类,CircleFactorySquareFactory,它们分别负责创建 CircleSquare 对象。

class CircleFactory(ShapeFactory):def create_shape(self) -> Shape:return Circle()class SquareFactory(ShapeFactory):def create_shape(self) -> Shape:return Square()

5. 客户端代码

在客户端代码中,我们通过工厂方法来创建图形对象,而不直接实例化具体类。

def draw_shape(factory: ShapeFactory):shape = factory.create_shape()shape.draw()# 客户端代码示例
circle_factory = CircleFactory()
draw_shape(circle_factory)square_factory = SquareFactory()
draw_shape(square_factory)

输出

Drawing a Circle! 
Drawing a Square! 

工厂方法模式的优势

  1. 解耦对象创建和使用:客户端不需要关心具体类的实现细节,而是通过工厂方法获取所需对象,这减少了与具体类的依赖。
  2. 扩展性强:新增产品类时,只需要添加新的具体工厂类,而不需要修改现有代码,符合开闭原则。
  3. 灵活性高:工厂方法模式使得客户端代码对具体类的依赖最小,提升了代码的灵活性和可维护性。

工厂方法模式 vs 简单工厂模式

尽管工厂方法模式和简单工厂模式看起来类似,但它们在设计上有一些显著的差异:

  • 简单工厂模式:一个工厂类负责创建所有类型的对象,客户端通过传递参数来决定创建哪个具体类的实例。缺点是随着产品种类增加,工厂类的代码会变得复杂,不易维护。

  • 工厂方法模式:每个具体工厂类负责创建一种特定类型的对象。客户端不需要关心对象的创建过程,只需要使用工厂方法来获取所需的对象。相比简单工厂模式,工厂方法模式在产品增加时不会让工厂类变得臃肿,代码更加灵活和可扩展。

适用场景

工厂方法模式适合于以下场景:

  • 产品类的创建过程复杂,且希望将创建过程封装起来,减少客户端与具体产品类的耦合。
  • 不希望让客户端知道产品的具体类名,而是通过工厂方法获取。
  • 希望在产品种类增加时,能够通过扩展工厂类来支持新的产品,而不是修改现有代码。

总结

工厂方法模式是一个非常强大的设计模式,它通过将对象的创建过程委托给子类工厂,减少了代码的耦合性,提高了系统的灵活性与可扩展性。它非常适合于产品种类不断增加且每种产品创建逻辑不同的场景。

理解并掌握工厂方法模式,可以帮助开发者在面对日益复杂的系统时,编写出更加灵活、可维护的代码。

相关文章:

设计模式-创建型-工厂方法模式

什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是 创建型设计模式之一,目的是通过定义一个用于创建对象的接口,让子类决定实例化哪个类。简而言之,工厂方法模式通过延迟对象的创建过程到子类来…...

如何判断一个学术论文是否具有真正的科研价值?ChatGPT如何提供帮助?

目录 1.创新性与学术贡献的超级加分✔ 2.科研过程中的各个环节—从0到1✔ 3.创新性与理论深度的完美结合✔ 4.论证与写作的清晰性✔ 5.数据整理和文献回顾——效率与精准并存✔ 6.创新性要求辅助✔ 总结 宝子们,学术论文写作的旅程是不是感觉像是走进了迷雾森…...

Linux驱动开发--字符设备驱动开发

一、概述 字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节 流进行读写操作的设备,读写数据是分先后顺序的。比如我们最常见的点灯、按键、 IIC、 SPI, LCD 等等都是字符设备,这些设备的驱动就叫做字符设备驱动。 Linux 应用程序对驱动程…...

Java 网络原理 ①-IO多路复用 || 自定义协议 || XML || JSON

这里是Themberfue 在学习完简单的网络编程后,我们将更加深入网络的学习——HTTP协议、TCP协议、UDP协议、IP协议........... IO多路复用 ✨在上一节基于 TCP 协议 编写应用层代码时,我们通过一个线程处理连接的申请,随后通过多线程或者线程…...

828华为云征文|使用sysbench对Flexus X实例对mysql进行性能测评

目录 一、Flexus X实例概述 1.1?Flexus X实例 1.2?在mysql方面的优势 二、在服务器上安装MySQL 2.1 在宝塔上安装docker 2.2 使用宝塔安装mysql 2.3 准备测试数据库和数据库表 三、安装sysbench并进行性能测试 3.1 使用yum命令sysbench 3.2?运行?sysbench 并进行…...

数据结构:堆

目录 1.堆的概念 2.堆的结构 3.堆的初始化 4.堆的销毁 5.堆的插入 6.堆的删除 7.判断堆是否为空 1.堆的概念 堆的性质: 堆中某个结点的值总是不大于或不小于其父结点的值; 堆总是一棵完全二叉树。 以下堆的结构默认大堆 : 2.堆的结…...

洪水灾害多智能体分布式模拟示例代码

1. 环境定义:支持灾害动态、地理数据和分布式架构 import numpy as np import random import matplotlib.pyplot as plt# 新疆主要城市及邻接关系 XINJIANG_CITIES {Urumqi: [Changji, Shihezi],Changji: [Urumqi, Shihezi, Turpan],Shihezi: [Urumqi, Changji, K…...

基于 Ragflow 搭建知识库-初步实践

基于 Ragflow 搭建知识库-初步实践 一、简介 Ragflow 是一个强大的工具,可用于构建知识库,实现高效的知识检索和查询功能。本文介绍如何利用 Ragflow 搭建知识库,包括环境准备、安装步骤、配置过程以及基本使用方法。 二、环境准备 硬件要…...

Selenium实践总结

1.使用显示等待而不是隐式等待 隐式等待可能会导致不可预测的测试行为,尤其是在动态 Web 应用程序中。显式等待,它允许您 等待特定条件发生后再继续测试,这种方法提供了更多的控制和可靠性。 WebDriverWait wait new WebDriverWait(drive…...

华为麦芒5(安卓6)termux记录 使用ddns-go,alist

下载0.119bate1 安卓5和6版本,不能换源,其他源似乎都用不了,如果root可以直接用面具模块 https://github.com/termux/termux-app/releases/download/v0.119.0-beta.1/termux-app_v0.119.0-beta.1apt-android-5-github-debug_arm64-v8a.apk 安装ssh(非必要) pkg install open…...

Springboot jar包加密加固并进行机器绑定

获取机器码,通过classfinal-fatjar-1.2.1.jar来获取机器码 命令:java -jar classfinal-fatjar-1.2.1.jar -C 对springboot打包的jar进行加密功能 java -jar classfinal-fatjar-1.2.1.jar -file lakers-ljxny-3.0.0.jar -packages com.lygmanager.laker…...

【Microi吾码】开源力量赋能低代码创新,重塑软件开发生态格局

我的个人主页 文章专栏:Microi吾码 一、引言 在当今数字化浪潮汹涌澎湃的时代,软件开发的需求呈现出爆发式增长。企业为了在激烈的市场竞争中脱颖而出,不断寻求创新的解决方案以加速数字化转型。传统的软件开发方式往往面临着开发周期长、技…...

系统思考—冰山模型

“卓越不是因机遇而生,而是智慧的选择与用心的承诺。”—— 亚里士多德 卓越,从来不是一次性行为,而是一种习惯。正如我们在日常辅导中常提醒自己:行为的背后,隐藏着选择的逻辑,而选择的根源,源…...

Java读取InfluxDB数据库的方法

本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、tag等。 首先,创建一个Java项目,用于撰写代码。如果大家是基于IDEA来创建项目,则可…...

【mybatis-plus问题集锦系列】在mybatisplus中无法autowired的原因排查及解决

mybatisplus简化了我们做数据操作,大大提升了我们的开发速度,但是今天在做测试的时候,突然报了这么个错误,排查好久才找到解决方案,特此记录下 问题复现 这里的测试方法报错,通过不了测试 org.springf…...

python中Windows系统使用 pywin32 来复制图像到剪贴板,并使用 Selenium 模拟 Ctrl+V 操作

步骤 1:安装必要的库 首先,安装 pywin32 和 selenium: pip install pywin32 selenium 如果使用的是 macOS,可以安装 pyobjc: pip install pyobjc 步骤 2:使用 pywin32 复制图像到剪贴板 在 Windows 系统中…...

uniapp——微信小程序,从客户端会话选择文件

微信小程序选择文件 文章目录 微信小程序选择文件效果图选择文件返回数据格式 API文档: chooseMessageFile 微信小程序读取文件,请查看 效果图 选择文件 /*** description 从客户端会话选择文件* returns {String} 文件路径*/ const chooseFile () &g…...

点亮核心板小灯 STM32U575

将核心板上的运行状态指示灯点亮 任务分析 灯如何点亮 如何看开发板原理图 开发板上的灯硬件组成 原理图 原理图(Schematic Diagram),也称为电路图或电气图,是一种图形表示方法,用于展示电子系统或电路的工作原理和…...

“图书馆服务自动化”:基于SSM框架的图书借阅系统开发

3.1系统的需求分析 需求分析阶段是设计系统功能模块的总方向,可以这样来说,系统的整个的开发流程以及设计进度,基本上都是以需求分析为基本依据的[10]。需求分析阶段可以确定系统的基本功能设计,以及在最后的系统验收阶段&#xf…...

顶顶通呼叫中心中间件的三种呼叫方式(mod_cti基于FreeSWITCH)

顶顶通呼叫中心共有三种呼叫方式: 手拨呼叫点击呼叫自动外呼 联系我们 有意向了解呼叫中心中间件的用户,可以点击该链接添加工作人员:https://blog.csdn.net/H4_9Y/article/details/136148229 手拨呼叫 手拨呼叫属于常规的呼叫方式&…...

HCIA笔记9--NAT、ACL与链路聚合

1. ACL ACL: 访问控制列表, Access Control List。 通过定义规则来允许或拒绝流量的通过。 1.1 ACL分类 1.2 配置实例 如图所示,对R2的访问只允许192.168.1.0/24网段。 我们可以配置基本acl来限制 acl 2000 acl number 2000 rule 5 permit source 192.168.1.0 0…...

【笔记】在虚拟机中通过apache2给一个主机上配置多个web服务器

(配置出来的web服务器又叫虚拟主机……) 下载apache2 sudo apt update sudo apt install apache2 (一)ip相同 web端口不同的web服务器 进入 /var/www/html 创建站点一和站点二的目录文件(目录文件名自定义哈&#x…...

“校园健康数据管理”:疫情管控系统的信息收集与分析

3.1可行性分析 通过对系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1 技术可行性 1.硬件可行性分析 校园疫情管控系统系统的硬件要求方面不存在特殊的要求&#xff0c…...

MySQL 中存储金额数据一般使用什么数据类型

在 MySQL 中存储金额数据时,应该谨慎选择数据类型,以确保数据的精度和安全性。以下是几种常用的数据类型及其适用性: DECIMAL 类型: 描述:DECIMAL 类型是专门为存储精确的小数而设计的。它可以指定小数点前后的数字位数…...

使用 .NET 6 或 .NET 8 上传大文件

如果您正在使用 .NET 6,并且它拒绝上传大文件,那么本文适合您。 我分享了一些处理大文件时需要牢记的建议,以及如何根据我们的需求配置我们的服务,并提供无限制的服务。 本文与 https://blog.csdn.net/hefeng_aspnet/arti…...

帝国cms电脑pc站url跳转到手机站url的方法

本文讲解一下帝国cms电脑网站跳转到手机动态网站和手机静态网站的方法,笔者以古诗词网 www.gushichi.com为例,为大家介绍操作步骤。方法一:帝国pc站跳转到手机静态站 1、假设我们有帝国cms 电脑网站www.XXX.com,手机网站m.XXX.com &#xf…...

D类音频应用EMI管理

1、前言 对于EMI,首先需要理解天线。频率和波长之间的关系,如下图所示。   作为有效天线所需的最短长度是λ/4。在空气中,介电常数是1,但是在FR4或玻璃环氧PCB的情况下,介电常数大约4.8。这种效应会导致信号在FR4材…...

【行业发展报告】2024大数据与智能化行业发展浅析

回首 2024,大数据智能化浪潮汹涌。海量数据宛如繁星,在智能算法的苍穹下汇聚、碰撞,释放出洞察市场与用户的强大能量,精准勾勒出商业新航线。我们精心雕琢技术架构,从数据存储的坚固基石到处理分析的高效引擎&#xff…...

闲谭Scala(3)--使用IDEA开发Scala

1. 背景 广阔天地、大有作为的青年,怎么可能仅仅满足于命令行。 高端大气集成开发环境IDEA必须顶上,提高学习、工作效率。 开整。 2. 步骤 2.1 创建工程 打开IDEA,依次File-New-Project…,不好意思我的是中文版:…...

系统压力测试助手——stress-ng

1、背景 在系统性能测试和压力测试中,stress-ng 是一个非常强大的工具,广泛应用于对 Linux 系统进行各种硬件和软件方面的负载测试。它能够模拟多种极端负载情况,帮助开发人员和运维人员检查系统在高负载下的表现,以便发现潜在的…...

FFmpeg推拉流命令

命令简介 它可以将本地的视频/音频流推送到服务器,也可以将服务器上的音视频流拉到本地。 推流命令的命令格式 ffmpeg -re -i [输入文件] -c:v [视频编码器] -c:a [音频编码器] -f [输出格式] [推流地址] 参数解析 -re 表示采用实时模式,以原始速度…...

【Spring】基于注解的Spring容器配置—— @Component及其衍生注解

Spring框架因其灵活性和强大的功能被广泛应用于企业级应用的开发中。Spring提供了一种基于IoC(控制反转)和AOP(面向切面编程)的编程模型,使得开发者能够以更简单和高效的方式管理应用程序的对象及其依赖关系。 在Spri…...

基于统计分析与随机森林的环境条件对生菜生长的影响研究

1.项目背景 随着现代农业的发展,对植物生长过程中环境因素的影响有了越来越多的关注,基于2023年8月3日至2023年9月19日期间记录的70个不同生菜样本的生长数据进行分析,可以更好地理解温度、湿度、pH值和总溶解固体(TDS&#xff0…...

基于PyQt5的UI界面开发——多界面切换

介绍 最初,因为课设的缘故,我只是想做一个通过按键进行切面切换而已,但是我看网上资料里面仅是语焉不详,让我困惑的很,但后面我通过摸索才发现这件事实在是太简单了,因此我想要记录下来。 本博客将介绍如…...

C语言-结构体内存大小

#include <stdio.h> #include <string.h> struct S1 { char a;//1 int b;//4 char c;//1 }; //分析 默认对齐数 成员对齐数 对齐数(前两个最小值) 最大对齐数 // 8 1 …...

搭建vue项目

一、环境准备 1、安装node node官网&#xff1a;https://nodejs.org/zh-cn 1.1、打开官网&#xff0c;选择“下载”。 1.2、选择版本号&#xff0c;选择系统&#xff0c;根据需要自行选择&#xff0c;上面是命令安装方式&#xff0c;下载是下载安装包。 1.3、检查node安装…...

【每日学点鸿蒙知识】Text填充父控件、Native接收数组、js逻辑不执行问题、UIAbility上下文问题、页面跳转路由栈

1、HarmonyOS 如何使Text组件填充满父组件&#xff1f; build() {Row() {Row() {Text(this.str).constraintSize({ maxWidth: 100%, minHeight: "30vp" }).backgroundColor(Color.Gray).fontSize(24vp)}.key(row1).constraintSize({ maxWidth: 100%}).backgroundCol…...

Debian-linux运维-ssh配置(兼容Jenkins插件的ssh连接公钥类型)

系统版本&#xff1a;Debian 12.5、11.1 1 生成密钥对 可以用云服务商控制台生成的密钥对&#xff0c;也可以自己在客户端或者服务器上生成&#xff0c; 已经有密钥对就可以跳过这步 用户默认密钥文件路径为 ~/.ssh/id_rsa&#xff0c;可以在交互中指定路径&#xff0c;也可…...

37. socketserver模块

一、socketserver模块 SocketServer 是标准库中的一个高级模块&#xff0c;它的目标是简化很多样板代码&#xff0c;它们是创建网络客户端和服务器所必须的代码。这个模块中有为你创建的各种各样的类。 类描述BaseServer包含核心服务器功能和 min-in 类的钩子&#xff1b;仅用…...

【详细讲解】hive优化

1、开启本地模式 大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过&#xff0c;有时Hive的输入数据量是非常小的。在这种情况下&#xff0c;为查询触发执行任务消耗的时间可能会比实际job的执行时间要多的多。对于大多数这种情况&#xff0c;Hive可…...

芝法酱学习笔记(2.3)——shardingsphere分库分表

一、前言 之前的例子中&#xff0c;我们以一个简化了的销售单报表查询&#xff0c;展示了大数据量查询时&#xff0c;在索引和变量类型层面可以做的一些优化。可我们发现&#xff0c;无论怎么优化&#xff0c;一次查询都要好几秒。 这是一个现实问题&#xff0c;只要一个系统用…...

【超简单】Python入门实用教程

Python 入门教程 1 ---- Python Syntax Python是一个高效的语言&#xff0c;读和写的操作都是很简单的&#xff0c;就像普通的英语一样 Python是一个解释执行的语言&#xff0c;我们不需要去编译&#xff0c;我们只要写出代码即可运行 Python是一个面向对象的语言&#xff0c;…...

c语言中void关键字的含义和用法

在 C 语言中&#xff0c;void 是一个特殊的关键字&#xff0c;主要有以下几个用途&#xff1a; 1. 表示函数没有返回值 当一个函数不需要返回任何值时&#xff0c;可以将其返回类型声明为 void。 #include <stdio.h>void printMessage() {printf("Hello, World!\…...

数据库课程设计-工资管理系统-MySQL

目录 第一节 需求分析 1.1 需求分析概述 1.2 功能需求分析 1.2.1 人事数据管理模块 1.2.2 考勤数据管理模块 1.2.3 工资数据管理模块 1.2.4 工资计算公式设置模块 1.3 数据需求分析 1.3.1 数据项定义 1.3.2 数据结构定义 第二节 概念结构设计 2.1 分E-R图 ?2.2 基…...

基于 DINOv2 模型实现图搜图相似度检索任务

一、DINOv2 模型简介及使用 DINOv2是由Meta AI开发的第二代自监督视觉变换器模型&#xff0c;采用 Vision Transformer (ViT) 架构 。其核心特点是在无需人工标签的情况下&#xff0c;通过自监督学习技术&#xff0c;从海量无标注图像中学习有意义的视觉特征表示&#xff0c;类…...

Excel将混乱的多行做成1列

目标是将数据按从左到右&#xff0c;再从上到下排成一列。 公式法 首先用textjoin函数将文本包起来&#xff0c;做成一个超长文本。 然后用公式 截取文本 Mid(m1,n,3)&#xff0c;意思就是对m1单元格&#xff0c;从第n个字符开始&#xff0c;截取3个字符出来。 这个公式如何自…...

2021.12.28基于UDP同信的相关流程

作业 1、将TCP的CS模型再敲一遍 服务器 #include <myhead.h> #define PORT 8888 #define IP "192.168.124.123" int main(int argc, const char *argv[]) {//创建套接字//绑定本机IP和端口号//监听客户端请求//接收客户端连接请求//收发消息//创建套接字int…...

DevOps工程技术价值流:Ansible自动化与Semaphore集成

在DevOps的浪潮中&#xff0c;自动化运维工具扮演着举足轻重的角色。Ansible&#xff0c;作为一款新兴的自动化运维工具&#xff0c;凭借其强大的功能和灵活性&#xff0c;在运维领域迅速崭露头角。本文将深入探讨Ansible的特点、架构、工作原理&#xff0c;以及其应用场景&…...

【 Git 设置代理】

【 Git 设置代理】 1. 设置代理2. 检查当前 Git 代理3. 测试代理是否正常4. 查看Git所有配置5. 取消添加的代理 1. 设置代理 添加 HTTP 和 HTTPS 代理&#xff1a; git config --global http.proxy http://127.0.0.1:10809 git config --global https.proxy http://127.0.0.1…...

使用 HTML 和 CSS 实现绚丽的节日烟花效果

文章目录 1. 效果预览2. 核心技术栈3. 核心代码解读3.1 HTML结构3.2 霓虹文字的CSS样式3.2.1 核心样式代码3.2.2 动画效果 3.3 JavaScript 的烟花效果实现3.3.1 烟花上升3.3.2 粒子爆炸 4. 用户交互5. 运行步骤总结 1. 效果预览 打开后输入文本的展示内容 用户点击页面后播放…...