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

news2024/11/17 17:45:47

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

简单工厂

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

请添加图片描述
从简单工厂的类图可知,简单工厂仅抽象了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.coloradmin.cn/o/1621433.html

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

相关文章

第四百七十七回

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容,本章回中将介绍GetMaterialApp组件.闲话休提,让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…

【HTML】页面引用Vue3和Element-Plus

在现代前端开发中,Vue 3 和 Element Plus 是非常受欢迎的技术。Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架,而 Element Plus 是一个基于 Vue 3 的组件库,提供了丰富的 UI 组件,帮助开发者快速构建高质量的前端应用。 …

【Java | 多线程】LockSupport 的使用和注意事项

了解一下 LockSupport LockSupport是一个类,位于java.util.concurrent.locks包中,提供了基本的线程同步机制。 LockSupport的主要作用是挂起和唤醒线程。它提供了两个主要的静态方法:park()和unpark()。 park():用于挂起当前线…

成都百洲文化传媒有限公司电商服务怎么样?

在当今数字化浪潮席卷全球的背景下,电商行业异军突起,成为连接消费者与品牌之间的重要桥梁。在这股变革之风中,成都百洲文化传媒有限公司以其专业的电商服务,成为行业的佼佼者,助力众多品牌踏上腾飞之路。 一、专业铸…

【Java 解析全国详细地址】Java 利用正则表达式完美解析全国省市区地址

这里写自定义目录标题 Java使用正则解析省市区/县 具体地址问题场景上demo运行结果 Java使用正则解析省市区/县 具体地址 问题场景 OCR识别营业执照 获取详细地址并拆分 上demo import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import j…

前端开发攻略---封装calendar日历组件,实现日期多选。可根据您的需求任意调整,可玩性强。

1、演示 2、简介 1、该日历组件是纯手搓出来的,没依赖任何组件库,因此您可以随意又轻松的改变代码,以实现您的需求。 2、代码清爽干净,逻辑精妙,您可以好好品尝。 3、好戏开场。 3、代码(Vue3写法&#xff…

ROS下机器人系统仿真及部分SLAM建图

文章目录 一、 Launch文件使用二、 参考资料三、 遇到的问题四、 效果演示五、相关代码5.1 一些简介5.2 机器人模型5.2.1 机器人底盘5.2.2 摄像头5.2.3 雷达 5.3 惯性矩阵 六、代码传送门实验结果及分析 温馨提示:如果有幸看到这个文章,不要看里面的内容…

bugku-杂项-社工进阶收集

下载附件 得到图片 利用百度地图查找 这里得到地点名称大雁塔音乐喷泉 陕西省西安市,大雁塔北广场 打开高德地图 来到大雁塔北广场 因为在北广场,所以地铁站为大雁塔站 开始分析 坐七站到大雁塔站,即始发站为韦曲南站 因为始发站离她家800米&…

Vue3的监听属性watch和计算属性computed

监听属性watch 计算属性computed 一、监听属性watch watch 的第一个参数可以是不同形式的“数据源,watch 可以监听以下几种数据: 一个 ref (包括计算属性)、 一个响应式对象、 一个 getter 函数、 或多个数据源组成的数组 watch 的参数:监视的回调&…

如何用stata画出文献中常见的安慰剂检验图?如何解决

🏆本文收录于「Bug调优」专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&…

Twisted 与 Tornado 中的 WebSocket 连接问题及解决方案

1、问题背景 项目中我们需要通过 Tornado HTTP 处理程序建立WebSocket连接,该连接需要处理多个用户请求,并且将从外部服务器获取的数据存储到数据库中。我们尝试了以下实现: from twisted.internet import reactor from autobahn.websocket…

R可视化:ggplot2绘制双y轴图

介绍 ggplot2绘制双y轴图加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE) library(tidyverse) library(readxl)# rm(list = ls()) options(stringsAsFactors = F) options(future.globals.maxSize = 10000 * 1024^2)Importing data 下载Underdetection of c…

【性能测试】ChaosTesting(混沌测试)ChaosBlade(混沌实验工具)(六)-servelt

7. servelt接口规范 7.0 创建servelt blade create servlet 7.0.1 介绍 Servlet 是 Java 的 web 的接口规范,Java web 服务器都遵循此规范实现。本场景主要模拟 Java Web 请求延迟、异常场景。 [blade create servlet delay](blade create servlet delay.md) 请…

【网安小白成长之路】9.sql注入操作

🐮博主syst1m 带你 acquire knowledge! ✨博客首页——syst1m的博客💘 🔞 《网安小白成长之路(我要变成大佬😎!!)》真实小白学习历程,手把手带你一起从入门到入狱🚭 &…

Vue:vue的工程化

Vue前端工程化 前后端分离开发 即前端人员开发前端工程,将开发好的前端工程打包部署在前端服务器上 后端开发人员开发后端工程,再将后端工程打包部署在后端服务器上,这种模式称为前后端分离开发 而前后端要顺利对接的关键就是要遵循一定的开发规范 开发规范 这种开发规范定…

STC8H8K64U I2C主机模式相关寄存器

STC8H8K64U I2C主机模式相关寄存器 STC8H8K64U-TSSOP20 I2CCFG I2C配置寄存器 I2CMSCR I2C主机控制寄存器 I2CMSST I2C主机状态寄存器 I2CMSAUX I2C主机辅助控制寄存器 I2CTXD I2C数据发送寄存器 I2CRXD I2C数据接收寄存器 I2CCFG I2C配置寄存器 B7ENI2C ENI2C&#xff1a…

【题解】NowCoder DP4 最小花费爬楼梯

题目来源:牛客 DP4 最小花费爬楼梯 题目描述: 给定一个整数数组 cost , 其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用,下标从 0 开始。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 你可以选择从…

Bayes判别示例数据:鸢尾花数据集

使用Bayes判别的R语言实例通常涉及使用朴素贝叶斯分类器。朴素贝叶斯分类器是一种简单的概率分类器,基于贝叶斯定理和特征之间的独立性假设。在R中,我们可以使用e1071包中的naiveBayes函数来实现这一算法。下面,我将通过一个简单的示例展示如…

多目标果蝇算法及其MATLAB实现

果蝇算法最早的文献是由台湾华夏科技大学的潘文超教授于2011年提出来的。该算法是基于果蝇觅食行为的仿生学原理而提出的一种新兴群体智能优化算法,被称为果蝇优化算法(Fruit Fly Optimization Algorithm, FOA)。通过模拟果蝇利用敏锐的嗅觉和视觉进行捕食的过程&am…

JTS:Java Topology Suit

接口文档:org.locationtech.jts:jts-core 1.19.0 API。 开发文档:JTS | Documentation。 概述 JTS提供了平面线性几何(planar and linear geometry)与相关的基础几何处理函数(a set of fundamental geometric functions.)。 JTS遵循OGC发布的简单几何规范(Simple Featu…