设计模式-工厂模式/抽象工厂模式

工厂模式

定义

        定义一个创建对象的接口,让子类决定实列化哪一个类,工厂模式使一个类的实例化延迟到其子类;

  • 工厂方法模式是简单工厂模式的延伸。在工厂方法模式中,核心工厂类不在负责产品的创建,而是将具体的创建工作交给子类去完成。也就是后所这个核心工厂仅仅只是提供创建的接口,具体实现方法交给继承它的子类去完成。当我们的系统需要增加其他新的对象时,我们只需要添加一个具体的产品和它的创建工厂即可,不需要对原工厂进行任何修改,这样很好地符合了“开闭原则”。

类图

角色

  • Product :抽象产品。所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类可以引用这个接口,而不是具体类

  • ConcreteProduct :具体产品

  • Creator:抽象工厂,它实现了所有操纵产品的方法,但不实现工厂方法。Creator 所有的子类都必须要实现

  • ConcreteCreator:具体工厂。制造产品的实际工厂。它负责创建一个或者多个具体产品,只有ConcreteCreator 类知道如何创建这些产品。

优缺点

  • 优点:
    • 在工厂方法中,用户只需要知道所要产品的具体工厂,无须关心具体的创建过程,甚至不需要具体产品的类名。
    • 在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对工厂进行任何修改,很好的符合了“开闭原则”
  • 缺点:
    • 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

使用场景

  • 一个类不知道它所需要的对象的类。在工厂方法模式中,我们不需要具体产品的类名,我们只需要知道创建它的具体工厂即可
  • 一个类通过其子类来指定创建那个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象。在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无需关系是哪一个工厂子类创建产品子类,需要时再动态指定。

抽象工厂模式

定义

        提供一个创建一系列或相关依赖对象的接口,而无需指定它们具体的类;

类图

角色

  • 抽象工厂角色:描述具体工厂的公共接口,是具体工厂的父类
  • 具体工厂角色:描述具体工厂,创建产品的实例,供外界调用,主要实现了抽象工厂中的抽象方法,完成具体产品的创建
  • 抽象产品角色:抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公共接口,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个工厂方法,因为所有创建的具体产品对象都是其子类对象。
  • 具体产品角色:具体产品角色是简单工厂模式的创建目标,所有创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的抽象方法,由具体工厂来创建,它同具体工厂之间一一对应。

产品族和产品等级

  • 产品族:一个品牌下面的所有产品;例如华为下面的手机,路由器,电脑称为华为产品的产品族
  • 产品等级:多个品牌下面的同种产品;例如华为和小米下面的手机 称为一个产品等级

优缺点

  • 优点
    • 提供了一种封装对象创建过程的方式:抽象工厂模式将对象的创建过程封装在了具体的工厂类中,客户端只需要关注工厂接口和产品接口,而无需关心具体的实现细节。
    • 实现了产品族的切换:通过使用不同的具体工厂类,可以方便的切换整个产品族的产品,从而实现了接口与实现的分离
    • 保持了代码的一致性:抽象工厂模式保持了一致性,即所有由同一工厂创建的产品都相互关联,使得产品之间可以很方便的进行配合使用。
  • 缺点
    • 不易扩展新的产品:当需要给产品家族新增一个产品时,需要修改抽象工厂的接口及所有的具体工厂类,这就违反了开闭原则,增加了代码的维护成本。
    • 增加了系统的复杂度:抽象工厂模式引入了多个抽象和具体类,增加了系统的复杂度和理解难度。

使用场景

  • 必须创建一系列相互关联或相互依赖的产品对象
  • 需要提供一个统一的接口,将客户端与具体实现解耦
  • 需要在运行时切换不同的产品族

使用案例

  • GUI 工具包:不同的操作系统(如Windows、Linux)提供了不同的GUI工具包,抽象工厂模式可以用于创建具体的按钮、文本框等GUI组件。
  • 数据库访问:数据库访问框架可以根据配置文件或运行时参数选择不同的数据库访问驱动,抽象工厂模式可以用于创建不同类型的数据库连接和操作对象。
  • 游戏开发:在游戏开发中,可以使用抽象工厂模式来创建不同种类的角色、武器、装备等物品。

要点总结

1. 如果没有应对“多系列 对象构建” 的需求变化,则没有必要使用Abstract Factory 模式,这时候使用简单工厂完全可以;

2. “系列对象”指的是在某一特定系列下的对象之间有相互依赖,或作用的关系。不同系列的对象之间不能相互依赖。

3. Abstract Factory 模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/954153.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Chatper 4: Implementing a GPT model from Scratch To Generate Text

文章目录 4 Implementing a GPT model from Scratch To Generate Text4.1 Coding an LLM architecture4.2 Normalizing activations with layer normalization4.3 Implementing a feed forward network with GELU activations4.4 Adding shortcut connections4.5 Connecting at…

Unity ShaderGraph中Lit转换成URP的LitShader

ShaderGraph中的LitShader如下: 在顶点和片元着色器暴露出了上图中的几个参数,要转换成URPLitShaderLab,首先要找到这几个参数,打开LitShader,找到第一个Pass,可以看到下图中的顶点和片元的定义函数,还有引…

uni-app的学习

uni-app 有着跨平台支持、丰富的插件和生态系统、高性能、集成开发工具HBuilderX的配合使用。允许使用者仅通过一套代码发布到多平台使用。 uni-app官网 uni-app 是一个适合开发跨平台移动应用和小程序的框架,能够大幅提高开发效率。 一、了解 1.1 工具准备 从Git…

USRP X310 Windows 烧录镜像

说明 USRP-X 系列设备包含两个用于两个以太网通道的 SFP 端口。由于 SFP 端口支持 1 千兆 (SFP) 和 10 千兆 (SFP) 收发器,因此 UHD 附带了多个 FPGA 图像,以确定上述接口的行为。 注意:Aurora 图像需要从 FPGA 源代码手动构建。 FPGA 图像…

Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器

Spring Boot – 动态启动/停止 Kafka 监听器 当 Spring Boot 应用程序启动时,Kafka Listener 的默认行为是开始监听某个主题。但是,有些情况下我们不想在应用程序启动后立即启动它。 要动态启动或停止 Kafka Listener,我们需要三种主要方法…

Docker save load 镜像 tag 为 <none>

一、场景分析 我从 docker hub 上拉了这么一个镜像。 docker pull tomcat:8.5-jre8-alpine 我用 docker save 命令想把它导出成 tar 文件以便拷贝到内网机器上使用。 docker save -o tomcat-8.5-jre8-alpine.tar.gz 镜像ID 当我把这个镜像传到别的机器,并用 dock…

计算机网络(三)——局域网和广域网

一、局域网 特点:覆盖较小的地理范围;具有较低的时延和误码率;使用双绞线、同轴电缆、光纤传输,传输效率高;局域网内各节点之间采用以帧为单位的数据传输;支持单播、广播和多播(单播指点对点通信…

浅谈云计算01 | 云计算服务的特点

在当今数字化时代,云计算作为一种强大的技术解决方案,正逐渐改变着企业和个人对信息技术的使用方式。本文将详细探讨云计算的五个主要特点,包括按需自助服务、广泛的网络接入、资源池化、快速弹性伸缩以及可计量服务。 一、按需自助服务 云…

【Qt】01-了解QT

踏入QT的殿堂之路 前言一、创建工程文件1.1 步骤介绍1.2 编译介绍方法1、方法2、编译成功 二、了解框架2.1 main.cpp2.2 .Pro文件2.2.1 注释需要打井号。2.2.2 F1带你进入帮助模式2.2.3 build文件 2.3 构造函数 三、编写工程3.1 main代码3.2 结果展示 四、指定父对象4.1 main代…

DDD - 微服务设计与领域驱动设计实战(上)_统一建模语言及事件风暴会议

文章目录 Pre概述业务流程需求分析的困境统一语言建模事件风暴会议什么是事件风暴(Event Storming)事件风暴会议 总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服务、实体与值对…

ssh2详细使用步骤,以及常用方法介绍

开源地址:https://github.com/mscdex/ssh2 ssh2 是一个功能强大的 Node.js 库,用于通过 SSH 协议与远程服务器交互。它支持命令执行、文件上传下载、端口转发等操作,常用于自动化脚本和远程服务器管理。 下面是 ssh2 的详细使用步骤和常用方…

Leetcode 377. 组合总和 Ⅳ 动态规划

原题链接&#xff1a;Leetcode 377. 组合总和 Ⅳ 可参考官解 class Solution { public:int combinationSum4(vector<int>& nums, int target) {vector<int> dp(target 1);dp[0] 1;// 总和为 i 的元素组合的个数for (int i 1; i < target; i) {// 每次都…

从epoll事件的视角探讨TCP:三次握手、四次挥手、应用层与传输层之间的联系

目录 一、应用层与TCP之间的联系 二、 当通信双方中的一方如客户端主动断开连接时&#xff0c;仅是在客户端的视角下连接已经断开&#xff0c;在服务端的眼中&#xff0c;连接依然存在&#xff0c;为什么&#xff1f;——触发EPOLLRDHUP事件&#xff1a;对端关闭连接或停止写…

dockerfile实现lnmp

dockerfile实现lnmp 自定义镜像实现整个架构 (基础镜像centos7) nginx cd /opt mkdir nginx mysql php vim Dockerfile docker network create --subnet172.111.0.0/16 mynetwork #创建自定义网段 docker run -itd --name nginx -p 80:80 --cpu-quota 20000 -m 512m -v /op…

unity下载newtonsoft-json

Package Manager&#xff0c;输入com.unity.nuget.newtonsoft-json 右键Assets-Reinport All

python学opencv|读取图像(三十一)缩放图像的三种方法

【1】引言 前序学习进程中&#xff0c;我们至少掌握了两种方法&#xff0c;可以实现对图像实现缩放。 第一种方法是调用cv2.resize()函数实现&#xff0c;相关学习链接为&#xff1a; python学opencv|读取图像&#xff08;三&#xff09;放大和缩小图像_python opencv 读取图…

PyCharm 引用其他路径下的文件报错 ModuleNotFound 或报红

PyCharm 中引用其他路径下的文件提示 ModuleNotFound&#xff0c;将被引用目录添加到系统路径&#xff1a; # # 获取当前目录 dir_path os.path.dirname(os.path.realpath(__file__)) # # 获取上级目录 parent_dir_path os.path.abspath(os.path.join(dir_path, os.pardir))…

ClickHouse-CPU、内存参数设置

常见配置 1. CPU资源 1、clickhouse服务端的配置在config.xml文件中 config.xml文件是服务端的配置&#xff0c;在config.xml文件中指向users.xml文件&#xff0c;相关的配置信息实际是在users.xml文件中的。大部分的配置信息在users.xml文件中&#xff0c;如果在users.xml文…

自动连接校园网wifi脚本实践(自动网页认证)

目录 起因执行步骤分析校园网登录逻辑如何判断当前是否处于未登录状态&#xff1f; 书写代码打包设置开机自动启动 起因 我们一般通过远程控制的方式访问实验室电脑&#xff0c;但是最近实验室老是断电&#xff0c;但重启后也不会自动连接校园网账户认证&#xff0c;远程工具&…

iOS 解决两个tableView.嵌套滚动手势冲突

我们有这样一个场景&#xff0c;就是页面上有一个大的tableView&#xff0c; 每一个cell都是和屏幕一样高的&#xff0c;然后cell中还有一个可以 tableView&#xff0c;比如直播间的情形&#xff0c;这个时候如果我们拖动 cell里面的tableView滚动的话&#xff0c;如果滚动到内…