设计模式之抽象工厂模式

前言

工厂模式一般指的是简单工厂模式、工厂方法模式、抽象工厂模式,这是三种工厂模式的最后一篇,其他两种的文章链接如下:

设计模式之简单工厂模式-CSDN博客

设计模式之工厂方法模式-CSDN博客

建议三种模式放在一起对比学习,更能领会其中的奥秘。看懂UML类图,更是奥秘中的奥秘哦,在UML类图中不同的箭头和线条,代表的意义是不同的,发现有很多人都画错了,这里简单的梳理了一下,如果需要可以移步这里:设计模式之基础:UML类图怎么看?_uml图怎么看-CSDN博客

什么是抽象工厂模式?

抽象工厂模式是一种创建型的工厂模式,它提供了一个接口,使客户端可以在不指定具体产品的情况下创建多个产品组中的产品对象。当存在多个抽象角色时,抽象工厂模式可以用来创建一个工厂,该工厂能够根据需要生成相应类型的产品。这种模式将产品的生成和使用解耦,使得客户端无需了解具体产品的实现细节。

抽象工厂模式的核心思想是将工厂封装成了一个抽象接口,通过这个接口来创建产品。它允许客户端通过调用抽象工厂的接口来生成多个产品族中的产品对象,而无需知道每个产品族的实现细节。抽象工厂模式适用于存在多个产品族的情况,这些产品族具有不同的实现,但是客户端需要使用多个产品族中的产品。通过使用抽象工厂模式,客户端可以灵活地使用不同的产品族,而无需对代码进行大量修改。

与工厂方法模式有什么区别?

抽象工厂模式和工厂方法模式都是设计模式中的对象创建型模式,主要用于封装对象的创建过程,以减少代码耦合。两种模式之间存在以下区别:

  1. 工厂角色不同:在工厂方法模式中,工厂方法是实现客户端与具体产品类解耦的关键,客户端通过继承或实现工厂方法实现创建产品的功能。而在抽象工厂模式中,抽象工厂是客户端与具体产品类解耦的关键,客户端通过实例化抽象工厂对象并调用其创建产品的方法实现创建产品的功能。
  2. 创建产品的模式不同:工厂方法模式中,每个具体工厂类只能创建一个具体产品类的实例,即“一对一”的关系。而在抽象工厂模式中,每个具体工厂类可以创建多个具体产品类的实例,即“一对多”的关系。
  3. 产品类型不同:在工厂方法模式中,工厂方法返回的产品类型是固定的,即每个具体工厂类只能创建一个固定类型的产品。而在抽象工厂模式中,抽象工厂返回的产品类型可以是多种多样的,即每个具体工厂类可以创建多个不同类型的产品。

总之,抽象工厂模式相对于工厂方法模式,更适用于创建一系列相关或相互依赖的对象,以及对产品进行分类和组织的情况。

抽象工厂UML类图

在抽象工厂模式中,存在四种角色:

  1. 抽象工厂角色(Abstract Factory):担任这个角色的是工厂方法模式的核心,它是与应用系统业务逻辑无关的。抽象工厂包含对多个产品结构的声明,任何工厂类都必须实现这个接口。
  2. 具体工厂角色(Concrete Factory):这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的业务逻辑紧密相关的。具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
  3. 抽象产品角色(Abstract Product):担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
  4. 具体产品角色(Concrete Product):抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。

抽象工厂实现示例

还以女娲造人的传说举一个例子:刚开始造人,女娲觉得还挺有意思的,造的时间长了,都是黄皮肤的中国人,显得很单调,没啥意思了,于是拓展了一下业务,开始造黑色皮肤的非洲人了,用抽象工厂模式来演示这个过程会是什么样呢?

UML类图如下:

伪代码示例如下:

public interface Human {/*** 人类会吃东西*/void eat();/*** 人类会喝东西*/void drink();
}
public class YellowMan implements Human {@Overridepublic void eat() {System.out.println("黄色皮肤的中国男人在吃东西");}@Overridepublic void drink() {System.out.println("黄色皮肤的中国男人在喝水");}
}
public class YelloWoman implements Human {@Overridepublic void eat() {System.out.println("黄色皮肤的中国女人在吃东西");}@Overridepublic void drink() {System.out.println("黄色皮肤的中国女人在喝水");}
}
public interface HumanFactory {Human createMan();Human createWoman();
}
public class YelloHumanFactory implements HumanFactory{@Overridepublic Human createMan() {return new YellowMan();}@Overridepublic Human createWoman() {return new YelloWoman();}
}
public class BlackHumanFactory implements HumanFactory{@Overridepublic Human createMan() {return new BlackMan();}@Overridepublic Human createWoman() {return new BlackWoman();}
}
public class Test {public static void main(String[] args) {HumanFactory yellowHumanFactory=new YelloHumanFactory();Human man = yellowHumanFactory.createMan();Human woman = yellowHumanFactory.createWoman();man.eat();man.drink();woman.eat();woman.drink();HumanFactory blackHumanFactory=new BlackHumanFactory();Human man1 = blackHumanFactory.createMan();Human woman1 = blackHumanFactory.createWoman();man1.eat();man1.drink();woman1.eat();woman1.drink();}
}

女娲这都造人业务都拓展到海外了,光能造黄种人、黑种人怎么行,还想造白种人怎么办呢?很简单:

1、实现Human接口,再实现一个白种男人、一个白种女人的类;

2、实现HumanFactory接口,再实现一个白种人的制造工厂;

public class WhiteMan implements Human {@Overridepublic void eat() {System.out.println("白种欧洲男人吃东西");}@Overridepublic void drink() {System.out.println("白种欧洲男人在喝水");}
}
public class WhiteWoman implements Human {@Overridepublic void eat() {System.out.println("白种欧洲女人在吃东西");}@Overridepublic void drink() {System.out.println("白种欧洲女人在喝水");}
}
public class WhiteHumanFactory implements HumanFactory{@Overridepublic Human createMan() {return new WhiteMan();}@Overridepublic Human createWoman() {return new WhiteWoman();}
}
public class Test {public static void main(String[] args) {HumanFactory whiteHumanFactory=new WhiteHumanFactory();Human man2 = whiteHumanFactory.createMan();Human woman2 = whiteHumanFactory.createWoman();man2.eat();man2.drink();woman2.eat();woman2.drink();}
}

有一天女娲觉得光造些男人、女人太单调了,男人、女人之间老是干架,怎么调合一下呢?那就造一些可爱小朋友吧。这时就会发现,如果还使用抽象工厂模式,就会很尴尬:HumanFactory接口里只有造男人、造女人的抽象方法,如果再加一个造小朋友的接口,就要对HuanFactory接口及其实现类具体工厂修改,这就破坏了开闭原则。如果除了造黑人、白人、黄人外,还想造点绿巨人,其实倒还好,和增加造白人的逻辑一样。这就是在决定是否使用抽象工厂模式的秘密所在,如果要扩展的是一个产品族,比较简单且适用,如果想丰富某一产品族的某个产品系列,就比较麻烦了;

抽象工厂应用场景

有没有发现这种方式非常好?完全符合开闭原则,无须对原有系统进行修改;下面就总结一下抽象工厂模式的实际应用场景有哪些?

  1. 产品组装:在现实生活中,抽象工厂模式最典型的例子就是产品的组装。例如,在电脑的组装过程中,我们通常需要选择一系列的配件,如CPU、硬盘、内存、主板、电源、机箱等。选择不同的配件,组装出来的电脑是不同的,这就可以看作是在使用不同的工厂来生产不同的产品。
  2. 提供产品类库:如果我们需要提供一个产品类库,但只想显示它们的接口而不是实现,那么就可以使用抽象工厂模式。例如,在设计一个绘图软件时,我们可能希望提供一个图形类库,但并不想暴露出每个图形的具体实现细节,这时就可以使用抽象工厂模式来生成各种图形对象。
  3. 多产品系列:如果一个系统需要由多个产品系列中的一个来配置,那么也可以使用抽象工厂模式。例如,在汽车制造中,可能需要根据用户的选择来配置不同的汽车模型。
  4. 独立于产品的创建、组合和表示:如果一个系统需要独立于它的产品的创建、组合和表示,那么也可以使用抽象工厂模式。例如,在开发一个游戏引擎时,我们可能希望游戏开发者能够使用我们提供的引擎来创建各种类型的游戏,而无需关心游戏引擎底层的具体实现。

总结

抽象工厂模式是一种设计程序时的工程方法,前面也说过,方法是为了解决问题的,不是灵丹妙药,用上了就一定很好,是绝不能生搬硬套的,重在理解和灵活运用。

对于抽象工厂模式有以下优点:

  1. 隔离了具体类的生成,使得客户端并不需要知道什么被创建。
  2. 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
  3. 增加新的产品族很方便,无须修改已有系统,符合开闭原则。

抽象工厂模式也有一些缺点:

  1. 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背了开闭原则。
  2. 如果客户端需要创建多个产品族的多个对象,那么代码会变得很冗长和复杂。
  3. 如果产品族之间有依赖关系,那么需要仔细考虑如何处理这些依赖关系,以避免出现循环依赖或其他问题。

因此,在使用抽象工厂模式时,需要根据具体的情况来考虑其优缺点,并决定是否使用该模式。

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

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

相关文章

亚马逊测评关于IP和DNS的问题

最近不少人询问了关于IP和DNS的问题,在此进行一些科普。 当客户端试图访问一个网站时,首先会向其所在的ISP的DNS服务器进行查询。如果ISP的DNS服务器没有相关缓存,则会向上级DNS服务器进行查询。 一些诸如CDN之类的服务,可能会为…

云安全—责任共担

0x00 前言 云安全的职责范围实际上一直遵循的是,谁提供谁负责,如果交付给云消费者的时候,交付者使用过程中就要自行负责,也就是我们经常遇到的配置不当等问题,在三层服务模式中,责任互相嵌套,最…

批量修改视频尺寸:简单易用的视频剪辑软件教程

如果你需要批量修改视频尺寸,同时保持高质量的画质,那么“固乔剪辑助手”这款软件是你的不二之选。下面就是如何使用这款软件进行批量修改视频尺寸的详细步骤。 1. 首先,你需要在浏览器中进入“固乔科技”的官网,然后下载并安装“…

大数据 DataX 数据同步数据分析入门

目录 一、DataX 概览 1.1 DataX 是什么 1.2 DataX 3.0 概览 设计理念 当前使用现状 二、DataX 详解 2.1 DataX 3.0 框架设计 2.2 DataX 3.0 插件体系 2.3 DataX 3.0 核心架构 2.3.1 核心模块介绍 2.3.2 DataX 调度流程 2.4 DataX 3.0 的六大核心优势 2.4.1 可靠的…

Linux考试复习整理

文章目录 Linux考试整理一.选择题1.用户的密码现象放置在哪个文件夹?2.删除文件或目录的命令是?3.显示一个文件最后几行的命令是?4.删除一个用户并同时删除用户的主目录5.Linux配置文件一般放在什么目录?6.某文件的组外成员的权限…

科技与时尚共进化,优衣库以硬实力创造品牌长期价值

时尚总是轮回,服装产品如何保持长青?对优衣库来说,产品力不褪色的密码之一,就是始终坚持推动服装科技与时尚融合,赋予生活潮流更多内涵,和更高品质的穿搭体验。 这一点,往往在每年换季新品上市…

2023年【氧化工艺】考试报名及氧化工艺考试总结

题库来源:安全生产模拟考试一点通公众号小程序 氧化工艺考试报名是安全生产模拟考试一点通总题库中生成的一套氧化工艺考试总结,安全生产模拟考试一点通上氧化工艺作业手机同步练习。2023年【氧化工艺】考试报名及氧化工艺考试总结 1、【单选题】 由和O…

多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)

多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制) 目录 多维时序 | MATLAB实现SSA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)预测效果基本描述模型描述程序设计参考资料 预测效果 基本…

企业微信设置可信域名

可信域名的验证文件注意一定放在域名所在的根目录下。 以cloud studio为例,工作区新建终端的路径就是域名在的根目录,而不是服务器的根目录

VA01/VA02/VA03 销售订单根据定价和步骤校验权限隐藏价格

1、业务需求 针对用户使用销售订单时,根据定价和步骤顺序,判断是否有权限,没有权限时隐藏销售订单抬头和行项目的部分价格数据 要限制的定价和步骤在spro中的位置 限制的步骤 2、增强实现 2.1权限对象 创建带有定价和步骤的权限对象 分配…

Jenkins+vue发布项目

在Jenkins 中先创建一个任务名称 然后进行下一步,放一个项目 填写一些参数 参数1: 参数2: 参数3:参数4: 点击保存就行了 配置脚本 // git def git_url http://gitlab.xxxx.git def git_auth_id GITEE_RIVER…

微服务拆分的思考

一、前言 前面几篇文章介绍了微服务核心的两个组件:注册中心和网关,今天我们来思考一下微服务如何拆分,微服务拆分难度在于粒度和层次,粒度太大拆分的意义不大,粒度太小开发、调试、运维会有很多坑。 二、微服务划分…

面试知识点--基础篇

文章目录 前言一、排序1. 冒泡排序2. 选择排序3. 插入排序4. 快速单边循环排序5. 快速双边循环排序6. 二分查找 二、集合1.List2.Map 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、排序 1. 冒泡排序 冒泡排序就是把小的元素往前调或者把大…

xray的使用

不需要扫描 点击 双击xray 1.打开 2.使用 主打扫描 3.被动扫描 网站 与 Burp 联动 - xray 安全评估工具文档 双击 xray cmd xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --html-output text.html 1.bp 2.这道这个 3.配置 xray 改为* 4.代理

一些ECharts配置

基于vue3&#xff0c;EChart5.4.3版本 Line <script setup lang"ts"> import {onBeforeUnmount, onMounted, ref, watch} from "vue" import {useEcharts, type ECOption} from "/composables" import * as echarts from "echarts/c…

全志A40i PRREMPT-RT Linux平台搭建IgH环境

1、编译安装内核 参考创龙开发板官方文档&#xff0c;在menuconfig中把gmac设置成M&#xff0c;方便卸载原始gmac驱动&#xff0c;然后加载优化后的实时网卡驱动 2、编译IgH 把IgH主站代码放到开发板上&#xff0c;进行配置编译(配置和编译可以参考网上ubuntu…

tensorrt安装使用教程

一般的深度学习项目&#xff0c;训练时为了加快速度&#xff0c;会使用多GPU分布式训练。但在部署推理时&#xff0c;为了降低成本&#xff0c;往往使用单个GPU机器甚至嵌入式平台&#xff08;比如 NVIDIA Jetson&#xff09;进行部署&#xff0c;部署端也要有与训练时相同的深…

python学习7

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

GEE:对二值图层进行腐蚀和/或膨胀操作

作者:CSDN @ _养乐多_ 腐蚀和膨胀 是数学形态学图像处理中的两个基本操作,用于修改和分析二值图像(包含只有两个像素值的图像,通常是黑和白)。这些操作可用于处理遥感图像、地理信息系统(GIS)中的栅格数据以及其他领域的图像处理。 腐蚀(Erosion):腐蚀是一种用于缩小…

电脑出现关于kernelbase.dll文件找不到的情况,有什么办法可以解决?

在使用电脑中&#xff0c;突然提示找不到kernelbase.dll&#xff0c;这时候应该怎么办呢&#xff1f;出现这样的问题&#xff0c;有神办法可以解决。看到有小伙伴在问这个问题&#xff0c;那么今天就带大家了解一下这个文件&#xff0c;同时教大家如何解决kernelbase.dll丢失的…