一文学透设计模式——抽象工厂模式

创建者模式
抽象工厂模式
概念
抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这是很多地方对于抽象工厂模式的描述,说实话感觉不是特别好懂。
按我的理解,用大白话讲,就是定义一套工厂的规范,按照这套规范可以创建很多的工厂,生产出不同的产品。
我们拿牛马人生公司为例。
假如苹果公司找到了牛马人生公司,跟牛马人生公司说,你帮我代加工生产手机和汽车等等一系列苹果公司的产品,但是要求生产苹果产品的工厂内必须只能生产苹果公司的产品。
牛马人生公司满口答应,多大点事对吧。
第二天,又有一个雪梨公司也找到了牛马人生公司,也要求代加工雪梨公司的产品,要求跟苹果公司一样。
牛马人生公司想了想也同意了。
牛马人生公司找到了工厂设计人员,总工程师想了想,苹果公司跟雪梨公司生产的产品都是一样的,何不设计一套工厂的规范,按照此工厂规范建造的工厂,就能满足苹果、雪梨这类的科技公司,后面还有什么西瓜公司、南瓜公司,也都可以按照这套规范来建造工厂。
于是乎,工厂创建规范出炉了,规范定义了,必须要有手机生产流水线、汽车组装流水线等等。
这一套定义工厂创建规范,并按照规范创建工厂,生产对应产品的思路就是抽象工厂模式。
实现步骤
下面我们用代码来表示这个逻辑。
-
首先我们定义了一个抽象类
AbstractFactory,用来表示工厂的创建规范,如下面的代码所示,我们定义了这一类的工厂,必须要有生产手机和汽车的能力。规范里并没有告诉工厂要怎么生产产品,这些在具体的工厂中去完成。/*** 抽象工厂。* 抽象工厂里定义了这个工厂所能获取的所有产品(对象)。具体创建这些产品的行为在子类中实现。** @author wanggt* @date 2023-06-17 11:19:21*/ public abstract class AbstractFactory {/*** 生产手机。** @param model 型号** @author wanggt* @date 2023-06-17 11:22:34*/public abstract Phone producePhone(String model);/*** 生产汽车。** @param color 颜色** @author wanggt* @date 2023-06-17 11:26:02*/public abstract Car produceCar(String color); } -
我们的规范中除了定义了工厂的规范,还简单地定义了生产出来的产品有什么功能。例如,手机得可以打电话吧,汽车得能走吧。这些功能可能不同的公司实现的方式不同,比如有些汽车用油,有些汽车用电。规范里不管,我只说明,得有这个功能,才能叫做汽车。
/*** 手机的接口定义。** @author wanggt* @date 2023-06-17 11:26:37*/ public interface Phone {/*** 拨打电话。** @author wanggt* @date 2023-06-17 11:27:28*/void call(String targetNum); }/*** 汽车的接口定义。** @author wanggt* @date 2023-06-17 11:27:45*/ public interface Car {/*** 往前冲。** @author wanggt* @date 2023-06-17 11:28:28*/void run(); } -
现在开始按照规范来打造工厂了。苹果工厂中手机流水线生产出来的手机是苹果手机
ApplePhone,汽车流水线生产出来的是苹果汽车AppleCar。/*** 苹果工厂。** @author wanggt* @date 2023-06-17 11:29:43*/ public class AppleFactory extends AbstractFactory {@Overridepublic Phone producePhone(String model) {return new ApplePhone(model);}@Overridepublic Car produceCar(String color) {return new AppleCar(color);} }/*** 苹果手机** @author wanggt* @date 2023-06-17 11:32:44*/ public class ApplePhone implements Phone {private final String model;public ApplePhone(String model) {this.model = model;}@Overridepublic void call(String targetNum) {System.out.println("你好,我是苹果手机,型号 " + model + ",你是" + targetNum);} }/*** 苹果汽车** @author wanggt* @date 2023-06-17 16:57:03*/ public class AppleCar implements Car {private final String color;public AppleCar(String color) {this.color = color;}@Overridepublic void run() {System.out.println("我是苹果汽车,我百公里加速1秒");} } -
按照规范打造了雪梨工厂,雪梨工厂中手机流水线生产出来的手机是雪梨手机
PearPhone,汽车流水线生产出来的是雪梨汽车PearCar。/*** 雪梨工厂。** @author wanggt* @date 2023-06-17 11:30:21*/ public class PearFactory extends AbstractFactory {@Overridepublic Phone producePhone(String model) {return new PearPhone(model);}@Overridepublic Car produceCar(String color) {return new PearCar(color);} }public class PearPhone implements Phone {private final String model;public PearPhone(String model) {this.model = model;}@Overridepublic void call(String targetNum) {System.out.println("你好,我是雪梨手机,型号 " + model + ",你是" + targetNum);} }public class PearCar implements Car {private final String color;public PearCar(String color) {this.color = color;}@Overridepublic void run() {System.out.println("我是雪梨汽车,百公里加速100秒");} } -
苹果公司看到雪梨公司也建了一个跟他一样的公司,这还得了,立马联系上了牛马人生公司的商务部门,要求多增加一套苹果工厂。牛马人生公司的商务部门向高层领导投诉,设计部门写的规范太难懂了,这不是他们商务部门要去研究的东西。这个时候,设计部门给商务部门提供了一套规则。如果是
apple公司,就创建AppleFactory工厂,如果是pear公司,就创建PearFactory工厂。商务很满意,设计这么简单,这不是有手就行。public class FactoryProducer {/*** 获取工厂。** @param company 公司** @author wanggt* @date 2023-06-17 14:11:05*/public static AbstractFactory getFactory(String company) {if ("apple".equalsIgnoreCase(company)) {return new AppleFactory();} else if ("pear".equalsIgnoreCase(company)) {return new PearFactory();} else {return null;}} } -
工厂红红火火开工了,工厂建好之后,又试运行了下流水线,一台台手机,一辆辆汽车从工厂里生产出来,总设计师感到很满足。终于又为公司干了点实事,今年的裁员应该轮不到他了吧。
public class AbstractFactoryPatternDemo {public static void main(String[] args) {// 创建一个苹果公司的工厂,并生产对应的产品AbstractFactory appleFactory = FactoryProducer.getFactory("apple");Phone phone = appleFactory.producePhone("11");phone.call("1234567890");Car appleCar = appleFactory.produceCar("白色");appleCar.run();System.out.println("====================");// 创建一个雪梨公司的工厂,并生产对应的产品AbstractFactory pearFactory = FactoryProducer.getFactory("pear");Phone pearPhone = pearFactory.producePhone("30");pearPhone.call("12343453464562");Car pearCar = pearFactory.produceCar("黄色");pearCar.run();} }你好,我是苹果手机,型号 11,你是1234567890 我是苹果汽车,我百公里加速1秒 ==================== 你好,我是雪梨手机,型号 30,你是12343453464562 我是雪梨汽车,百公里加速100秒
优缺点分析
我们现在来分析下总工程师设计的这一套工厂创建规范。
优点就是按照这套工厂创建规范打造出来的工厂,生产出来的产品都是同一个产品族的,要么都是苹果公司的产品,要么都是雪梨公司的产品。进入苹果工厂,闭着眼睛也能知道,里面生产的全部苹果公司的产品。手机必定是苹果手机,而不可能是雪梨手机。
而且接下来如果有类似的公司找到牛马人生公司的时候,完全可以按照这套工厂创建规范,再创建一个西瓜工厂即可。
但是缺点也是有的。总工程师摸了摸下巴,没有告诉其他人这个缺点。
那就是假如以后苹果公司增加了一些产品,例如苹果飞机,那必然就要修改工厂创建规范。修改了工厂创建规范之后,还得去扩建苹果工厂,去增加这个流水线。
但是雪梨公司并不会生产飞机,那么这个时候,雪梨工厂里面出现了一点问题,雪梨工厂里面有为生产飞机的预留位置,实际上并不会生产飞机,这多少让雪梨公司的人不爽。因为那为生产飞机预留的位置,似乎一直在提醒他们,你雪梨公司就是比苹果公司差。
相关文章:
一文学透设计模式——抽象工厂模式
创建者模式 抽象工厂模式 概念 抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这是很多地方对于抽象工厂模式的描述,说实话感觉不是特别好懂。…...
Vue3与Vue2区别和总结(1)
在2020年9月18日,Vue.js发布3.0版本,代号:One Piece(海贼王) 既然vue2已经存在了六七年之久为什么还要研发vue3呢? 那就不得不提vue3带来的提升了 1.Vue3带来了什么 1.性能的提升 打包大小减少41% 初次…...
【华秋推荐】物联网入门学习模块 ESP8266
随着全球信息技术的不断进步和普及,物联网成为当今备受关注的技术热点之一。通过物理和数字设备之间的连接来实现自动化和互联互通的网络。无线传感器、云计算和大数据分析等技术,物联网使设备能够相互交流和共享信息,实现智能化的自动化操作…...
本科专科毕业论文如何选题-附1000多论文题目-论文选题--【毕业论文】
文章目录 本系列校训毕设的技术铺垫论文选题选题目的和意义:选题举例参考文献 配套资源 本系列校训 互相伤害互相卷,玩命学习要你管,天生我才必有用,我命由我不由天! 毕业论文不怕难,毕业设计来铺垫&#…...
pip安装jupyter notebook
之前电脑安装了anaconda,里面安装了jupyter notebook,用来做PPT之类的展示总让我觉得有点“炫酷”。 现在换了新电脑。没有anaconda,纯粹只是装了python3.11,然后突然也想手工安装下jupyter notebook,于是只能通过pip方…...
STM32刷Micropython固件参考指南
STM32刷Micropython固件指南 其实刷固件和普通的程序下载烧录无多大的差异,主要是其他因数的影响导致刷固件或刷完固件无法运行的情况和相关问题。 📑刷固件教程 固件下载。目前所支持的stm32型号有这些: stm32f0, stm32f4, stm32f7, stm32g…...
学生信息管理系统自动化测试
项目地址: http://82.156.151.156:8080/login.html 一、系统测试用例 二、测试实现过程 先是根据自己的项目设计了一个 UI 自动化测试用例, 然后根据这个测试用例使用了 selenium4自动化测试工具和 JUnit5单元测试框架结合实现的 web 自动化测试.。 测试模块划分…...
Java面向对象之toString()方法
toString()方法 toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。在进行String与其它类型数据的连接操作时,自动调用toString()方法。 Date nownew Date(); System.out.println(“now”now); 相当于 System.…...
MySQL(一)
mysql简介 1、什么是数据库 ? 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅仅…...
使用docker部署node和react应用
使用docker部署node和react应用 Docker 使开发人员能够将所有应用程序打包到容器中。这些容器可以在任何安装了 Docker 的机器上运行,并且应用程序将是相同的。这是在多个系统上运行代码库克隆的好方法,并且我们可以确保它们都是相同的。 在本文中&…...
对List集合、数组去重
前言: 还记得在2021我发布的第一篇博客就是关于数组的去重,从那一刻开始,命运的齿轮开始转动…… 扯远了哈哈哈,我重新写这篇文章只是想让去重方式更加严谨(ps:我才不会说是因为技术成长了,看不上之前写的…...
AI相机“妙鸭相机”原理分析和手动实现方案
妙鸭相机 一个通过上传大约20张照片,生成专属自拍。在2023年7月末爆火,根据36Kr报道,妙鸭相机系阿里系产品,挂靠在阿里大文娱体系下,并非独立公司。 使用方法是上传20张自拍照片,之后可以选择模板生成自己…...
关于计算机大学生秋招面试的那点事?(Golang篇)
前言; Go语言(简称Golang)越来越受到开发者的关注和欢迎。它由Google公司于2009年推出,旨在提供更好的性能和并发性能。眼下,越来越多的公司在使用它,比如著名的云计算服务商AWS,以及知名电商京…...
Windows网络自学的第一天:创建线程
CreateThread函数: 该函数用于创建一个新的线程并在其上运行指定的函数,原型如下: HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID …...
正确的 Java 异常处理
我们来谈谈痛点吧。由于我的职责,我必须使用许多不同的服务(进行编辑、进行代码审查......);不同的团队通常会编写所有这些服务,每当涉及到处理错误并从服务转发错误时,有时我的眼睛就会开始流泪。让我尝试…...
RTT(RT-Thread)时钟管理
目录 时钟管理 时钟节拍 RTT工程目录结构介绍 配置文件:rtconfig.h 获取系统节拍 获取系统节拍数函数 实例 定时器 RT_Thread定时器介绍 定时器源码分析(了解即可) rt_system_timer_init (硬件定时器初始化) rt_system_timer_thr…...
基础实验篇 | uORB消息读写与自定义实验(二)
导读 uORB是PX4/Pixhawk系统中非常重要且关键的模块之一,是用于无人机模块间通信的协议机制。本篇将详细介绍uORB并详细拆解uORB消息读写与自定义实验全流程(二)。 基础实验篇 | uORB消息读写与自定义实验(二) 01 RflySim平台的uORB消息读写…...
k8s pod数据存储Volumes
一、说在前面的话 在 Kubernetes 的 Deployment 中,您可以使用多种类型的 Volumes 来管理 Pod 中的数据。 作用是用来共享目录及配置,不用在每个pod里进行配置。 本文主要概述怎么使用HostPath、PersistentVolumeClaim、ConfigMap。 二、k8s有哪些Vol…...
ZYNQ在Petalinux系统下双网口同网段的实现
ZYNQ在Petalinux系统下双网口同网段的实现 1.开发环境 采用了赛灵思zynq xc7z100芯片,外部挂载了两个网口phy芯片(marvell 88e1510),且两个网口phy芯片公用MDIO管脚,bd配置如下: 2.问题说明 忙去了&am…...
突破传统监测模式:业务状态监控HM的新思路 | 京东云技术团队
一、传统监控系统的盲区,如何打造业务状态监控。 在系统架构设计中非常重要的一环是要做数据监控和数据最终一致性,关于一致性的补偿,已经由算法部的大佬总结过就不再赘述。这里主要讲如何去补偿?补偿的方案哪些?这就…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
