简单工厂、工厂方法、抽象工厂对比

简单工厂、工厂方法和抽象工厂是三种常见的工厂设计模式,它们在软件设计中各有其独特的应用场景和优缺点。因为三种设计模式都属于工厂模式,在实际应用中可能存在误用的场景,这里对其做下对比,以便更好的理解这三种设计模式。

简单工厂

简单工厂模式并不在二十三个标准的设计模式中,可以将简单工厂模式看成工厂方法模式的退化实现。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类,所以也将简单工厂称为静态工厂方法模式。其类图表示如下:

请添加图片描述
从简单工厂的类图可知,简单工厂仅抽象了Product,而对于创建Product的Factory,则只有一个。
简单工厂模式适用于需要创建的Product比较少,且基本不会变化的情况。与其他的创建型模式一样,简单工厂将产品的创建从产品中分离出来,实现了职责分离。使用简单工厂可以减少工厂子类的创建,实现一定程度的简易性。但是简单工厂违反了面向对象设计的开闭原则。当需要增加新的Product时,需要修改工厂类的现有判断逻辑。在产品类型较多时,会导致工厂类演变成上帝类,同时,会造成工厂逻辑过于复杂,不利于系统的扩展。

工厂方法

工厂方法模式是最常用的工厂模式,通过定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法模式将类的实例化(具体Product的创建)延迟到工厂类的子类(具体工厂)中完成,即由子工厂类来决定该实例化哪一个类。其类图表示如下:

请添加图片描述

工厂方法模式适用于Product的子类较多且无法预知确切类型,或需要扩展软件库或框架中对象的创建等场景。与其他的创建型模式一样,工厂方法将创建产品的代码与实际使用产品的代码分离,实现了职责分离,避免了产品创建和实际产品之间的紧耦合。相比简单工厂,工厂方法在抽象Product的基础上,也对Factory进行了抽象,并要求每个Factory子类负责某一类Product的创建。这样,产品创建代码放在单独的类里,从而使得代码更容易维护,符合单一职责原则。当需要引入新的Product子类时,同步创建新的Factory子类,无需更改客户端调用代码,符合开闭原则。但是工厂方法解耦的设计,也带来代码复杂度上升的问题。因为需要为每个Product创建一个Factory子类,所以工厂模式会随着Product子类的增加,而同步增加Factory子类。针对这个问题,最好的情况是将该模式引入产品类的现有层次结构中(将工厂类组合到产品类里)。

抽象工厂

抽象工厂模式是所有工厂模式中最复杂的模式,通过提供一个创建一组相关或相互依赖的对象的接口,让每个子类生产一系列相关的Product。其类图表示如下:

请添加图片描述

抽象工厂适用于需要创建的多个不同系列的相关产品存在交互且无法预知对象确切类别及其依赖关系,或需要扩展软件库或框架中对象的创建等场景。与其他的创建型模式一样,抽象工厂将创建产品的代码与实际使用产品的代码分离,实现了职责的分离,避免产品创建和实际产品之间的紧耦合。与工厂方法一样,抽象工厂也对Factory进行了抽象,并要求每个Factory子类负责某一类Product的创建。这样,产品创建代码放在单独的类里,从而使得代码更容易维护,符合单一职责原则。当需要引入新的Product子类时,同步创建新的Factory子类,无需更改客户端调用代码,符合开闭原则。但是,相比工厂方法中每个Factory负责一个Product的创建,抽象工厂中的Factory负责一个产品系列相关产品的创建。抽象工厂解耦的设计,会带来比工厂方法更高的代码复杂度问题。在设计良好的程序中,每个类仅负责一件事。如果一个类与多种类型产品交互,就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。在实际的开发中,应首先考虑工厂方法,如果工厂方法仍无法满足需求,再考虑使用抽象工厂。

简单工厂、工厂方法、抽象工厂对比

无论简单工厂、工厂方法,还是抽象工厂,都是工厂模式,都是创建型模式。其主要职责都是将创建产品的代码与实际使用产品的代码分离,实现了职责分离,避免了产品创建和实际产品之间的紧耦合。相比工厂方法和抽象工厂,简单工厂没有对工厂进行抽象,而是将所有产品的创建都放在一个工厂里实现。虽然简单工厂可以减少子类工厂的创建,保证一定程度的代码的简易性。但是这样的设计模式是不符合面向对象设计的开闭原则。当需要增加新的Product时,需要修改现有工厂的判断逻辑。相比简单工厂,工厂方法和抽象工厂则增加了对工厂的抽象,将产品的创建分配到工厂子类。这样,产品创建的代码放在单独的子类里,使得代码更容易维护,符合单一职责原则。当需要引入新的Product子类时,同步创建新的Factory子类,无需更改客户端调用代码,这符合开闭原则。但是,工厂方法和抽象工厂因引入工厂子类,无疑也会带来代码复杂度上升的问题。对于工厂方法来说,每新增一个Product子类,就需要同步创建一个Factory子类。而对抽象工厂来说,每新增一个Product系列,就需要同步创建一个Factory子类。所以工厂模式或抽象工厂会随着Product子类或Product系列的增加,会同步增加Factory子类。
在实际的应用中,对于产品子类变化比较少的场景,可以先使用简单工厂,这样可以保证代码的简易性。当产品子类不断增加时,为了更好的隔离变化,需要为每个产品增加对应的工厂。如果产品种类进一步增加,则考虑使用抽象工厂。在工厂方法和抽象工厂的选取上,应优先选择工厂方法,如果工厂方法不能很好的隔离变化,则应进一步考虑使用抽象工厂。

参考

https://yiyan.baidu.com/ 文心一言
《设计模式:可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军, 马晓星 等译
https://zhuanlan.zhihu.com/p/158861140 工厂模式-简单工厂、工厂方法、抽象工厂解析
https://cloud.tencent.com/developer/article/2342470 设计模式学习笔记(三)简单工厂、工厂方法和抽象工厂之间的区别

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET周刊【4月第2期 2024-04-21】

国内文章 他来了他来了,.net开源智能家居之苹果HomeKit的c#原生sdk【Homekit.Net】1.0.0发布,快来打造你的私人智能家居吧 https://www.cnblogs.com/hezp/p/18142099 三合是一位不喜欢动态编程语言的开发者,对集成米家智能家居到苹果HomeK…

【Ant-Desgin-React 穿梭框】表格穿梭框,树穿梭框的用法

Antd Desgin 穿梭框 普通用法高级用法-表格穿梭框组件高级用法-树穿梭框组件 普通用法 /* eslint-disable no-unused-vars */ import React, { useEffect, useState } from react import { Space, Transfer } from antd// Antd的穿梭框组件Mock数据 const mockData Array.fro…

西安站开营!AI 编码助手通义灵码帮大学生“整活儿”

如何更好地与 AI 为伴,做时代的先进开发者?4 月 17 日,阿里云推出的 AI 编程助手通义灵码与云工开物“高校训练营”走进西安多所高校开启实操培训,结合 AI 辅助编程的发展背景、通义灵码的具体能力和应用实操,帮助在校…

全世界IT人苦竞业久矣!美国FTC宣布全面废除员工竞业协议

2023 年 1 月,美国联邦贸易委员会(FTC)发布声明称,拟在全国范围禁止用人单位与雇员签订竞业禁止性条款。当地时间 4 月 23 日,FTC 宣布全面禁止所有员工(包括高级管理人员)签署新的竞业禁止协议…

js生成不同的阅读数分配到每一篇上面,不会因为刷新而变动

js生成不同的阅读数分配到每一篇上面,不会因为刷新而变动 {%- for article in blog.articles -%}<div class"blog-articles__article article">{%- render article-card,article: article,media_height: section.settings.image_height,media_aspect_ratio: a…

xilinx Mailbox 中的ipi message地址计算方式

适用于openAmp mailbox ipi id对应的ipi message地址计算方式 官方openamp硬件配置解析 OpenAMP Base Hardware Configurations - Xilinx Wiki - Confluence openamp官方设备树 meta-openamp/meta-xilinx-tools/recipes-bsp/device-tree/files/zynqmp-openamp.dtsi at rel-v2…

SpringBoot+Vue开发记录(四)

说明&#xff1a; 本篇文章的主要内容是软件架构以及项目的前端Vue创建 一、软件架构 我道听途说的&#xff0c;听说这个东西很关键很重要什么的。 软件架构&#xff08;software architecture&#xff09;是一个系统的草图,是一系列相关的抽象模式&#xff0c;用于指导大型软…

AI商业智能的一些分享

本文主要讲AI商业相关的&#xff08;特别是营销相关的&#xff09;一些知识点&#xff0c;比较零散。 简单总结 AI商业智能&#xff1a; 1&#xff09;将人员经验抽象化为算法规则&#xff0c; 2)打造数据驱动的精益运营能力&#xff0c; 3)长期保持价格竞争力并将商品毛利让…

Day 21 LAMP架构和DNS域名

LAMP架构简介 针对不同的后端开发语言&#xff0c;使用不同的架构&#xff0c;后端项目开发语言有&#xff1a;Java&#xff0c;PHP&#xff0c;Python...... 针对于PHP项目 LAMP架构 LinuxApacheMysql/MariadbPhp LNMP架构 LinuxNginxMysql/MariadbPhp 针对于Java项目 w…

国密SSL证书在等保、关保、密评合规建设中的应用

在等保、关保、密评等合规建设中&#xff0c;网络和通信安全方面的建设是非常重要的部分&#xff0c;需要实现加密保护和安全认证&#xff0c;确保传输数据机密性、完整性以及通信主体可信认证。国密SSL证书应用于等保、关保和密评合规建设中&#xff0c;不仅能够提升网络信息系…

【C++】vector常用函数总结及其模拟实现

目录 一、vector简介 二、vector的构造 三、vector的大小和容量 四、vector的访问 五、vector的插入 六、vector的删除 简单模拟实现 一、vector简介 vector容器&#xff0c;直译为向量&#xff0c;实践中我们可以称呼它为变长数组。 使用时需添加头文件#include<v…

【Burpsuite靶场】XSS专题精讲

【个人】&#xff1a;NEUQ大一学生 【专业】&#xff1a;通信工程 (Communication Engineering) 【个人方向】&#xff1a;网安、开发双管齐下 【座右铭】&#xff1a;真正的英雄主义,就是看清生活的真相后依然热爱生活 -- 罗曼.罗兰 一、认识XSS&#xff08;跨站脚本攻击&…

零基础转行网络安全,难度大吗?

说有难度那是肯定会有的&#xff0c;事在人为&#xff0c;我之前是从事于Java后端开发的&#xff0c;后面转行学网络安全&#xff0c;花了些时间&#xff0c;现在拿到了比之前开发更高的薪资&#xff0c;觉得还是挺满足的&#xff01; 1.网络安全岗位 1.1安全运维工程师 负责监…

【Python数据库】MySQL

文章目录 [toc]创建数据库创建数据表数据插入数据查询数据更新 个人主页&#xff1a;丷从心 系列专栏&#xff1a;Python数据库 学习指南&#xff1a;Python学习指南 创建数据库 import pymysqldef create_database():db pymysql.connect(hostlocalhost, userroot, passwor…

Maven多模块快速升级超好用Idea插件-MPVP

功能&#xff1a;多模块maven项目快速升级指定版本插件&#xff0c;并提供预览和相关升级模块日志能力。 可快速进行版本升级&#xff0c;进行部署到Maven仓库。 安装&#xff1a; 可在idea插件中心进行安装 / 下载资源拖动安装 MPVP(Maven) - IntelliJ IDEs Plugin | Marke…

遥测终端赋能水库泄洪监测预警,筑牢度汛安全防线!

4月10日&#xff0c;水利部召开水库安全度汛视频会议。会议要求着力强化水库防洪“四预”措施&#xff0c;加快构建雨水情监测预报“三道防线”&#xff0c;完善预警信息发布机制&#xff0c;推进数字孪生水利工程建设&#xff0c;为科学调度指挥决策提供支持。强调坚决牢牢守住…

Ubuntu Pycharm安装

下载PyCharm&#xff0c;https://www.jetbrains.com/pycharm/download/?sectionlinux 然后按照下图执行安装&#xff1a; 安装的时候可能出现的问题&#xff1a; 问题1&#xff1a;No JDK found. Please validate either PYCHARM_JDK, JDK_HOME or JAVA_HOME environment var…

【熵与特征提取】从近似熵,到样本熵,到模糊熵,再到排列熵,包络熵,散布熵,究竟实现了什么?(第六篇)——“散布熵”及其MATLAB实现

今天讲散布熵&#xff0c;之前用了几篇文章分别讲述了功率谱熵、奇异谱熵、能量熵、近似熵、样本熵、模糊熵、排列熵、包络熵这8种类型的熵&#xff1a; Mr.看海&#xff1a;【熵与特征提取】基于“信息熵”的特征指标及其MATLAB代码实现&#xff08;功率谱熵、奇异谱熵、能量…

使用API有效率地管理Dynadot域名,自查账户信息

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

使用Python进行异常处理与日志记录的最佳实践

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python进行异常处理与日志记录的最佳实践 异常处理和日志记录是编写可靠且易于维护的软…