抽象工厂模式和工厂模式的区别?

2023-11-03



简单工厂模式

简单工厂模式不是23种里的一种,简而言之,就是有一个专门生产某个产品的类。 
比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标。


工厂模式

工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。 
戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。 
生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。 
后续直接调用鼠标工厂.生产鼠标()即可


抽象工厂模式

抽象工厂模式也就是不仅生产鼠标,同时生产键盘。 
也就是PC厂商是个父类,有生产鼠标,生产键盘两个接口。 
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。 
创建工厂时,由戴尔工厂创建。 
后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。


在抽象工厂模式中,假设我们需要增加一个工厂

假设我们增加华硕工厂,则我们需要增加华硕工厂,和戴尔工厂一样,继承PC厂商。 
之后创建华硕鼠标,继承鼠标类。创建华硕键盘,继承键盘类。 
即可。


在抽象工厂模式中,假设我们需要增加一个产品

假设我们增加耳麦这个产品,则首先我们需要增加耳麦这个父类,再加上戴尔耳麦,惠普耳麦这两个子类。 
之后在PC厂商这个父类中,增加生产耳麦的接口。最后在戴尔工厂,惠普工厂这两个类中,分别实现生产戴尔耳麦,惠普耳麦的功能。 
以上。

122 caoglish
知乎是整理自己思路的地方
142 人赞同了该回答
今天正好在学习抽象工厂和工厂方式,我就把我的理解写一写。

工厂一般理解就是减少new创建对象的方式,用接口的方式来返回一个对象,而new创建的方式被封装了。然而,这个是初级认识,这不足以理解到工厂方式的真正目的。

所以我要用我的方式帮助大家理解。

第一部分: 抽象工厂
一般来说,抽象工厂最简单形态也至少有4个元素:
  • 客户端(client)
  • 工厂(factory)
  • 产品A(product A)
  • 产品B(product B)

我先用一个例子来实体说明抽象工厂是什么

我现在有三个神枪手,他们聚在一起讨论他们玩枪的经历,
  • 神枪手1:AK47打枪最好,杀伤力大。
  • 神枪手2:沙漠之鹰最好,准。
  • 神枪手3:连弩才好,上古兵器。

他们争论相持不下,所以决定比试一下,然后约定一个月后来鄙视。然后我们看到三个人分别去各自的工厂去购买武器。


神射手1 去了AK47工厂,购买他们生产的武器和子弹


神射手2 去了沙漠之鹰工厂,购买他们生产的武器和子弹

神射手3,去了连弩工厂,购买他们生产的武器和“子弹”




一个月后,我们看到了3个人分别拿出来以下的武器组合



这三个人虽然用的武器不一样,但是每件武器都要做两件事


最后,他们通过比赛谁,看哪种武器是最优秀的。


我们回头去看看,发现虽然三个人去了不同的工厂,用了不同的武器,用了不同的子弹,但是他们的相似之处太多,可以抽象出来。抽象出来的关系框架就是抽象工厂模式

  • 武器工厂生产武器
  • 武器工厂生产武器所用的子弹
  • 武器可以装载子弹
  • 武器可以射击子弹
  • 神射手装载子弹
  • 神射手射击子弹

那么把关系画出来就是:

然后抽象一下成工厂模式就是:


图画出来了,然后我们要如何理解抽象工厂模式. 过去人们都是从工厂开始解释,其实我个人觉得,倒过来讲反而更好理解。而理解抽象工厂模式的关键在于如何理解“产品之间特定关系”。

  1. 用户要调用产品之间的这个特定关系
  2. 这个特定关系只有产品A和产品B之间才有,所以我们需要产品A和产品B
  3. 要获得产品A和产品B,我们要去生产这个产品A和产品B的那个工厂,叫工厂生产这个产品A和产品B

那么用例子来说,就是:

  1. 神枪手喜欢装载子弹和射击的感觉(他们就是喜欢这个,只要有武器符合这个条件就行)
  2. 那么他们就是需要武器(枪或者连弩)和子弹,这个武器是可以装载相应子弹和射击相应子弹的
  3. 他们可以去特定工厂(ak47工厂或者连弩工厂)要求购买武器和相应子弹、

所以理顺抽象工厂的特点是什么?就是如下几个特点:

  • 工厂是独立的(独立的类)
  • 工厂是生产一整套有产品的(至少要生产两个产品),这些产品必须相互是有关系或有依赖的
  • 工厂是可以抽象的,工厂生产是可以抽象的
  • 产品是可以抽象的,产品关系是可以抽象的
  • 客户端是用来调用并理顺这些产品之间的关系(或指定工作流程)
  • 不同工厂生产出的产品实例之间是不接触的,这个是靠客户端来封装实现的。
用一个例子来解释一下最后一条“不同工厂生产出的产品实例之间是不接触的,这个是考客户端来封装实现的”。
一个射击学员刚入门,听到射击老师说射击的几个要素: 武器,子弹,武器装载子弹,武器打出子弹。这个学员跃跃欲试,就跑到Ak47工厂买了枪,然后跑到沙漠之鹰工厂买了子弹,AK47装载沙鹰子弹,然后打出。学员卒。

老师听说后,为了避免这个悲剧发生,承包了武器和子弹购买,要用AK47就必须在AK47工厂购买AK47和AK47子弹,保证了AK47加载沙漠之鹰子弹这样的悲剧发生了。
这就是客户端加载工厂实例后,保证只使用这个工厂的生产的产品和产品之间的关系,确保不和其他工厂的产品实例进行接触。

最终当我们调用客户端的行为时候,只要让客户端“加载”实例化的特定工厂,返回结果就是这个“特定工厂”所加工出来的“特定产品”的“特定关系”方法的结果了。


所以,当产品非常多的时候,产品之间关系又非常复杂,但却又可以进行抽象的时候,就是使用抽象工厂模式最好的时候了。

以上就是抽象工厂模式的个人理解


--------

第二部分: 工厂方法


工厂方法就两个元素:

  • creator(创建者)
  • product(产品)

而工厂方法就是一个创建者这个类的一个方法而已,这个方法就是用来封装产品的创建。






(留坑)





第三部分: 抽象工厂 和工厂方法的不同点


我从一下几个方面来理解抽象工厂和工厂方法不同点

  • 抽象工程关键在于产品之间的抽象关系,所以至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,所以可以只生成一个产品。

  • 抽象工厂中客户端把产品的抽象关系理清楚,在最终使用的时候,一般使用客户端(和其接口),产品之间的关系是被封装固定的;而工厂方法是在最终使用的时候,使用产品本身(和其接口)。
抽象工厂更像一个复杂版本的策略模式,策略模式通过更换策略来改变处理方式或者结果;而抽象工厂的客户端,通过更改工厂还改变结果。所以在使用的时候,就使用客户端和更换工厂,而看不到产品本身。

工厂方法目的是生产产品,所以能看到产品,而且还要使用产品。当然,如果产品在创建者内部使用,那么工厂方法就是为了完善创建者,从而可以使用创建者。另外创建者本身是不能更换所生产产品的。


  • 抽象工厂的工厂是类;工厂方法的工厂是方法。
抽象工厂的工厂类就做一件事情生产产品。生产的产品给客户端使用,绝不给自己用。
工厂方法生产产品,可以给系统用,可以给客户端用,也可以自己这个类使用。自己这个类除了这个工厂方法外,还能有其他功能性的方法


其实仔细想想,这个两个模式是有交集的,在极端的情况下,这两个模式其实是一样的。所以可以这样理解
  • 给工厂方法模式加一个客户端,除了客户端都不用这个创建者。这个时候创建者就是工厂类了。(单一产品的特定关系这个时候就是没有关系)
  • 抽象工厂模式中,在客户端内部编程时候,就可以把工厂类当作创建者。


https://www.zhihu.com/question/20367734











本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

抽象工厂模式和工厂模式的区别? 的相关文章

  • 戴尔服务器调节风扇转速

    开机F10进入 Lifecycle 选择系统设置 高级硬件设置 选择iDARC设置 散热 散热选择最大性能 其余按需选择 点击 返回 完成 保存更改 一路点完成 然后重启
  • 时序预测

    时序预测 MATLAB实现IWOA BiLSTM和BiLSTM时间序列预测 改进的鲸鱼算法优化双向长短期记忆神经网络 目录 时序预测 MATLAB实现IWOA BiLSTM和BiLSTM时间序列预测 改进的鲸鱼算法优化双向长短期记忆神经网络

随机推荐

  • Go语言面试题--进阶提升(6)

    文章目录 1 下面的代码输出什么 2 下面的代码输出什么 3 下面的代码输出什么 4 下面的代码输出什么 5 下面代码有什么问题吗 6 下面代码输出什么 请说明 1 下面的代码输出什么 type T struct n int func ma
  • Android设备的序列号与ro.serialno

    Android设备的序列号是通过获取Property ro serialno 的值取得的 ro serialno 的值一般来源于内核启动参数中的 ro boot serialno 在rk3368 Android6 0中 uboot读取idb
  • 微信小程序项目刚建好编译就报错

    出现的错误如下 1 Cannot delete property WeixinJSBridge 2 Argument 0 must be a buffer source or a WebAssembly Module object 出现这个
  • 前端 阿拉伯数字不换行

    对于一般的div 自要设置了width 如果容器里面的文字过多 则文章就会自动换行 但是如果输入连续的英文字符 则设置的width 不会生效 容器会被撑开 比如 一般div超过宽度能换行 对于div p等块级元素 正常文字的换行 亚洲文字和
  • 挖矿病毒攻击的排查处置手册

    一 背景 在用户不知情或未经允许的情况下 占用系统资源和网络资源进行挖矿 影响用户的网络和资源 从而获取虚拟币牟利 为了帮助应对恶意挖矿程序攻击 发现和清除恶意挖矿程序 防护和避免感染恶意挖矿程序 整理了如下针对挖矿活动相关的现状分析和检测
  • 【FPGA基础篇】底层结构组成

    文章目录 前言 CPU和DSP FPGA ASIC对比 FPGA和CPLD比较 FPGA基础 IOB 输入输出单元 CLB 可编程逻辑模块 LUT 查找表 MUX 选择器 复用器 Carry Chain 进位链 Flip Flop 触发器
  • SHELL 脚本定期删除日志文件(日志定期清理)

    假设我们的应用每天会产生一个日志文件 但我们并没有对日志文件做任何归档处理 久而久之日积月累 就会将磁盘空间占满 从而影响系统的正常运行 分析磁盘空间占用情况 当前磁盘空间占用情况 df h 当前目录文件大小列表 ll lh 文件列表按时间
  • 解决Python的your data either using array.reshape(-1, 1) if your data has a single featur

    今天写关于决策树的一些算法的时候 卧槽 mmp 竟然出现了红色的警示错误 oneRowX 0 0 1 0 1 1 0 0 1 0 newRowX 1 0 0 0 1 1 0 0 1 0 Traceback most recent call
  • verilog开发调试入门

    verilog开发调试入门 日常踩坑 记录调试经验 希望帮到初学者 2022 09 26 非阻塞赋值 注意在时序电路内部使用 lt 仿真波形不动 检查代码无误后 考虑分频间隔过大 仿真长度不够 憨憨落泪 上板 生成比特流失败 遇如下警告 C
  • ios笔记--class关键字,Category,protocol和block笔记

    1 class关键字介绍 1 概念 只是声明是一个类 但是调用不了这个类里面的方法 2 作用 只是定义成员变量 属性 3 好处 当import导入的文件里面的方法变动了 引用的地方也要跟着改变 而且还需要重新编译一次 影响程序效率 但是使用
  • 计算机毕业设计-基于SSM的高校毕业生离校管理系统

    项目摘要 随着信息技术和网络技术的飞速发展 人类已进入全新信息化时代 传统管理技术已无法高效 便捷地管理信息 为了迎合时代需求 优化管理效率 各种各样的管理系统应运而生 各行各业相继进入信息管理时代 高校毕业生离校管理系统就是信息时代变革中
  • 详解 IntelliJ IDEA 配置和启动maven 项目 步骤

    一 从svn中检出web项目 1 如果是maven项目 首先配置仓库 2 从svn中检出maven项目 3 检查项目是否是maven项目 如果不是转化成maven 然后点击 更新jar 二 配置jdk SDK 1 点击 三 配置projec
  • 几种概率分布(伯努利分布、二项分布、泊松分布、均匀分布、正态分布、指数分布、伽马分布)

    伯努利分布 Bernoulli Distribution 又名两点分布或者0 1分布 是一个离散型概率分布 为纪念瑞士科学家雅各布 伯努利而命名 若伯努利试验成功 则伯努利随机变量取值为1 若伯努利试验失败 则伯努利随机变量取值为0 记其成
  • 这个cuda教程不错,一个链接

    http supercomputingblog com cuda tutorials
  • 遗传算法(Python)

    import numpy as np import matplotlib pyplot as plt from matplotlib import cm from mpl toolkits mplot3d import Axes3D 设定参
  • Servlet详解

    一 Servlet的生命周期 创建Servlet有两个时机 一是客户端第一次请求每个Servlet时 系统创建该Servlet实例 另外是Web应用启动时立即创建Servlet实例 即load on startup Servlet 每个Se
  • 解决问题:Visual Studio 2022 打开Qt设计文件xxx.ui报错

    文章目录 解决问题 Visual Studio 2022 打开Qt设计文件xxx ui报错 环境 问题描述 解决方案 在viusal studio中操作Qt的UI文件 解决问题 Visual Studio 2022 打开Qt设计文件xxx
  • 北航计算机科学与技术专业河北投档线,北京航空航天大学2020录取分数线(附2017-2020年分数线)...

    北京航空航天大学2020年录取分数线是多少 各专业录取分数线是多少 是每个填报 北京航空航天大学的考生最关注的问题 随着各省高考录取批次相继公布 考生也开始关心是否被 北京航空航天大学的录取 一品高考网整理相关信息供参考 希望对大家有帮助
  • 申请搜狐自媒体账号

    visualor 申请入驻搜狐公众平台 特此声明
  • 抽象工厂模式和工厂模式的区别?

    简单工厂模式 简单工厂模式不是23种里的一种 简而言之 就是有一个专门生产某个产品的类 比如下图中的鼠标工厂 专业生产鼠标 给参数0 生产戴尔鼠标 给参数1 生产惠普鼠标 工厂模式 工厂模式也就是鼠标工厂是个父类 有生产鼠标这个接口 戴尔鼠