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

「聊设计模式」之工厂方法模式(Factory Method)

🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,早日登顶🚀,欢迎持续关注&&收藏&&订阅!


前言

  设计模式是指在软件设计中,经过总结和提炼的,能够解决特定问题的经验性的总结。它不是一种可直接转化为代码的完整设计,而是一种描述在不同情况下如何解决问题的一种方案。

  工厂方法模式(Factory Method)是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂方法模式中,我们不会指定要创建哪个类的对象,而是由子类决定要创建哪个类的对象。这样我们就可以将对象的创建从代码中解耦,使得代码更加灵活。

  本文将围绕工厂方法模式展开,介绍它的定义、结构、实现、优缺点及适用场景。此外,本文还提供了Java代码实现和测试用例,帮助读者更好地理解工厂方法模式。

摘要

  本文将介绍工厂方法模式的定义、结构、实现、优缺点及适用场景。其中,定义部分阐述了什么是工厂方法模式,结构部分介绍了工厂方法模式的UML图和各个角色的职责,实现部分提供了Java代码实现,优缺点部分分析了工厂方法模式的优劣,适用场景部分列出了适用于工厂方法模式的情景。此外,本文还提供了测试用例以验证工厂方法模式的正确性。

工厂方法模式

如何定义?

  工厂方法模式定义:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式使一个类的实例化延迟到其子类。

  工厂方法模式通过定义一个抽象的工厂接口来声明创建产品对象的操作,而将实际创建工作推迟到子类中进行。这样做的好处是,我们可以针对不同的产品需求,提供一个统一的接口,而使用者只需要关心接口,而不需要关心具体的实现细节。在需要新增产品时,只需要添加一个新的产品类和相应的工厂类即可。

结构

工厂方法模式包含以下角色:

  1. 抽象工厂(Creator):提供一个创建产品的接口,它包含一个创建产品的抽象方法。在Java中,该接口通常由一个抽象类或者一个接口实现。

  2. 具体工厂(Concrete Creator):实现Creator接口中的创建产品方法,返回具体的产品实例。

  3. 抽象产品(Product):定义一个产品的抽象类,它包含了一些基本的属性和方法,这些方法或属性将会被具体的产品类所实现和覆盖。

  4. 具体产品(Concrete Product):实现抽象产品接口中定义的方法和属性。

工厂方法模式模拟

以下是工厂方法模式的Java代码实现。

抽象工厂

public interface Creator {Product createProduct();
}

具体工厂

public class ConcreteCreator implements Creator {@Overridepublic Product createProduct() {return new ConcreteProduct();}
}

抽象产品

public interface Product {void doSomething();
}

具体产品

public class ConcreteProduct implements Product {@Overridepublic void doSomething() {System.out.println("具体产品做了某些事情");}
}

测试用例

public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreator();Product product = creator.createProduct();product.doSomething();}
}

代码解析:
如上是一个简单的工厂模式的示例代码,包括以下几个部分:

  1. 客户端代码(Client):其中包含一个 main 方法,用来演示如何使用工厂模式创建产品并调用其方法。

  2. 抽象产品接口(Product):定义了产品的基本方法。

  3. 具体产品类(ConcreteProduct):实现了抽象产品接口中定义的方法。

  4. 抽象工厂接口(Creator):定义了工厂方法(createProduct),用来创建产品实例。

  5. 具体工厂类(ConcreteCreator):实现了抽象工厂接口中的工厂方法(createProduct),用来创建具体的产品实例。

  在客户端代码中,先创建了一个具体的工厂实例(ConcreteCreator),然后通过工厂实例的 createProduct 方法来创建一个具体的产品实例(ConcreteProduct)。最后调用产品实例的 doSomething 方法来执行具体的功能。

测试用例执行结果如下:

在这里插入图片描述

小结

  本文介绍了工厂方法模式的概念、实现、优点和应用。在工厂方法模式中,我们通过定义一个工厂接口来实现对象的创建,并且可以将对象创建的细节隐藏起来。通过使用工厂方法模式,我们可以将代码的复杂性降到最低,从而更容易进行扩展和维护。

优缺点

工厂方法模式有以下优点:

  1. 工厂方法模式将产品的实现和客户端代码隔离开来,使得客户端代码无需关心具体的产品实现细节。

  2. 工厂方法模式遵循了单一职责原则,每个工厂只负责生成一个产品,符合高内聚低耦合的设计思想。

  3. 工厂方法模式可以很方便地扩展新的产品,只需要添加相应的产品类和工厂类即可。

  4. 工厂方法模式可以很容易地用来创建工厂的实现,这使得代码更加灵活。

工厂方法模式也有以下缺点:

  1. 工厂方法模式的创建方法是由抽象工厂接口定义的,如果需要添加新的产品,就需要修改抽象工厂接口和所有具体工厂实现。

  2. 工厂方法模式虽然可以用于扩展新的产品,但是一旦产品族和产品等级的数量过多,就会导致类的数量急剧增加,从而使得系统难以维护。

适用场景

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

  1. 需要对产品实现进行抽象,客户端只需要调用抽象工厂接口,而不需要关心具体的实现细节。

  2. 需要动态添加新的产品,只需要添加相应的产品类和工厂类即可。

  3. 需要一个统一的工厂接口来创建产品,但是不希望客户端代码直接依赖于具体的实现。

  4. 需要遵循单一职责原则,使得每个工厂只负责一个产品的生成。

总结

  工厂方法模式是一种非常有用的设计模式,它可以帮助我们解决对象创建的问题,从而提高我们的代码的可维护性和可扩展性。在实际应用中,我们可以通过工厂方法模式来实现各种功能,例如对象的创建、事件的处理等等。因此,掌握工厂方法模式是非常重要的。

附录源码

如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

☀️建议/推荐你


  如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

📣关于我


我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。

相关文章:

「聊设计模式」之工厂方法模式(Factory Method)

🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,早日登顶🚀,欢迎持续关注&&收藏&&订阅! 前言 设计模式是指在软件设计中,经过总结和提炼的&#…...

局部变量,全局变量与内存

本文会使用IDA分析局部变量&#xff0c;全局变量在内存的存储 目录 使用IDA分析局部变量 使用IDA分析全局变量 总结 使用IDA分析局部变量 #include <stdio.h>int main() {int nNum 1;float fNum 2.5;char ch A;printf("int %d, float %f, char %c", nNu…...

Python爬虫异常处理实用技巧分享

当我们编写爬虫程序时&#xff0c;经常会遇到各种各样的异常情况&#xff0c;比如网络连接失败、页面解析错误、请求被拒绝等等。这些异常情况可能导致程序中断或者无法正常运行&#xff0c;给我们的数据采集工作带来一定的困扰。所以&#xff0c;掌握一些实用的异常处理技巧对…...

【性能测试】Jmeter —— jmeter计数器

jmeter计数器 如果需要引用的数据量较大&#xff0c;且要求不能重复或者需要递增&#xff0c;那么可以使用计数器来实现 如&#xff1a;新增功能&#xff0c;要求名称不能重复 1&#xff0c;新增计数器 计数器&#xff1a;允许用户创建一个在线程组之内都可以被引用的计数器…...

Python 布尔类型和比较运算符

视频版教程 Python3零基础7天入门实战视频教程 布尔( bool&#xff09;表达现实生活中的逻辑&#xff0c;即真和假&#xff0c;True表示真&#xff0c;False表示假。 实例&#xff1a; # 布尔类型定义 b1 True b2 False print(f"b1{b1},类型是{type(b1)}") prin…...

蓝牙核心规范(V5.4)10.1-BLE 入门笔记(1)

ble 规范 深入了解蓝牙LE需要熟悉相关的规格。蓝牙LE的架构、程序和协议由一项关键规范完全定义,称为蓝牙核心规范。产品如何使用蓝牙以实现互操作性由两种特殊类型称为配置文件和服务的规范集合所涵盖。图1展示了BLE规范类型及其相互关系。 1.1 蓝牙核心规范 蓝牙核心规范是…...

Java高级之泛型、自定义泛型、通配符的使用

泛型与File 文章目录 一、为什么要有泛型&#xff1f;1.1、什么是泛型&#xff1f;1.2、泛型的设计背景1.3、泛型的概念 二、在集合中使用泛型三、自定义泛型结构2.1、泛型方法的使用 四、泛型在继承上的体现五、通配符的使用5.1、通配符的使用5.2、有限制条件的通配符的使用 …...

代码随想录二刷day32

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣122. 买卖股票的最佳时机 II二、力扣55. 跳跃游戏三、力扣45. 跳跃游戏 II 前言 一、力扣122. 买卖股票的最佳时机 II class Solution {public int ma…...

linux基础篇

文章目录 linux基础篇1.Linux文件系统结构:2.常用的Linux指令&#xff1a;3.Shell指令&#xff1a;4.Linux服务管理&#xff1a;5.Linux磁盘挂载&#xff1a;其他 linux基础篇 1.Linux文件系统结构: 根目录 /bin目录&#xff1a;二进制可执行文件存放处boot目录&#xff1a;启…...

文心一言插件开发全流程,ERNIE-Bot-SDK可以调用文心一言的能力

文心一言插件开发 前言插件插件是什么工作原理申请开发权限 开始第一步&#xff1a;安装python第二步&#xff1a;搭建项目manifest 描述文件&#xff1a;ai-plugin.json插件服务描述文件&#xff1a;openapi.yaml开发自己的plugin-server 第三步&#xff1a;上传插件 SDK相关链…...

Keepalived+LVS负载均衡

Keepalived 是一个用于实现高可用性的开源软件&#xff0c;它基于 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;协议&#xff0c;允许多台服务器协同工作&#xff0c;以确保在某个服务器出现故障时服务的连续性。Keepalived 的核心思想是将多台服务器配置成…...

接口测试学习

1、curl 命令 无参&#xff1a;curl -X POST -H"Authorization: abcdefghijklmn" https://xxx.xxxxx.com/xxxx 有参&#xff1a;curl -X POST -H"Authorization:abcdefghijklmn " -H"Content-Type:application/json" https://xxx.xxxxx.com/…...

怎么用外网访问自己的网站?快解析内网端口映射来实现

想要访问服务器上的网站需要直接或间接访问服务器IP地址&#xff0c;但是如果服务器没有公网IP地址&#xff0c;那么就需要借助外网进行访问。当我们需要远程访问内网的Web服务器时&#xff0c;我们需要使用一些技术来实现此目的。这就需要通过使用类似快解析内网端口映射方式进…...

zabbix学习1--zabbix6.x单机

文章目录 1. 环境2. MYSQL8.02.1 单节点2.2 配置主从 3. 依赖组件4. zabbix-server5. agent5.1 yum5.2 编译 附录my.cnfJDK默认端口号 1. 环境 进入官网查看所需部署环境配置以及应用版本要求https://www.zabbix.com/documentation/current/zh/manual/installation/requiremen…...

Flink 的 Kafka Table API Connector

Flink datastream connectors 和 Flink table api connectors 的区别&#xff1a; Flink DataStream Connectors和Table API Connectors是Flink中用于连接外部数据源的两种不同的连接器。 1. Flink DataStream Connectors: - Flink DataStream Connectors是用于将外部数据源连…...

tcpdump 命令

一、TCPDUMP指定IP 在网络流量分析过程中&#xff0c;我们经常需要对指定的IP进行抓取和分析。使用TCPDUMP指定IP非常简单&#xff0c;只需要通过命令行参数-i指定需要抓取的网卡&#xff0c;并使用host参数指定目标IP地址即可&#xff1a;tcpdump -i eth0 host 192.168.0.1 上…...

哪些测试项目可以使用自动化测试?

通常&#xff0c;软件测试v的测试方式分为人工测试和自动化测试&#xff0c;人工测试是由测试人员编写并执行测试用例&#xff0c;然后观察测试结果与预期结果是否一致的过程;自动化测试是通过测试工具来代替或辅助人工去验证系统功能是否有问题的过程。 采用自动化测试需要满…...

【八大经典排序算法】冒泡排序

【八大经典排序算法】冒泡排序 一、概述二、思路解读三、代码实现四、优化 一、概述 冒泡排序由于其简单和易于理解&#xff0c;使其成为初学者学习排序算法的首选&#xff0c;也是初学者接触到的第一个排序算法。其原理是通过重复交换相邻的元素来将最大的元素逐步“冒泡”到…...

【IEEE会议】第五届机器人、智能控制与人工智能国际学术会议(RICAI 2023)

【IEEE列表会议】第五届机器人、智能控制与人工智能国际学术会议&#xff08;RICAI 2023&#xff09; 2023 5th International Conference on Robotics, Intelligent Control and Artificial Intelligence 第五届机器人、智能控制与人工智能国际学术会议&#xff08;RICAI 20…...

如何在本地 Linux 主机上实现 Yearning SQL 审核平台的远程访问?

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...