当前位置: 首页 > news >正文

Java设计模式-抽象工厂模式-一次性理解透

抽象工厂模式示意图

1. 抽象工厂模式简介

抽象工厂设计模式是创建型模式之一。抽象工厂模式与工厂模式几乎相似,只是它更像工厂中的工厂

如果您熟悉Java 中的工厂设计模式,或看过上一篇我写的“java简单工厂模式”,您会注意到我们有一个工厂类。此工厂类根据提供的输入返回不同的子类工厂类使用 if-else 或 switch 语句来实现这一点

但是在抽象工厂模式中,我们摆脱了 if-else 块,并为每个子类设置了一个工厂类。然后是一个抽象工厂类,它将根据输入的工厂类返回子类。起初,这似乎令人困惑,但一旦您看到实现,就很容易掌握和理解工厂和抽象工厂模式之间的细微差别。就像我们的工厂模式帖子一样,我们将使用相同的超类和子类。

2. 抽象工厂模式的原理

在这里插入图片描述
抽象工厂模式的角色包括:‌

  1. 抽象产品:‌定义了产品的规范和接口。‌
  2. 具体产品:‌实现了抽象产品的接口,‌是实际的产品对象。‌
  3. 抽象工厂:‌提供了创建产品的接口,‌但不负责实现这些接口。‌

抽象工厂模式通过提供一个创建一系列相关或相互依赖对象的接口,‌而无需指定它们具体的类,‌实现了产品的创建与使用的分离。‌这种模式特别适用于那些需要创建多个相关产品对象的场景,‌如组装电脑时选择CPU、‌硬盘、‌内存等配件,‌或者创建一个包含多种类型产品的产品族,‌如手机和电脑等电子产品。‌通过抽象工厂模式,‌可以更好地管理这些产品的创建和组合,‌提高系统的可维护性和可扩展性。‌

3. 抽象工厂的使用场景

下面,整理出了4中典型的关于“抽象工厂模式”的使用场景介绍。

3.1 系统独立于产品创建、‌组合和表示

当系统需要独立于其产品的创建、‌组合和表示时,‌抽象工厂模式可以提供一个统一的接口来创建一系列相关的产品对象,‌而不必关心具体的实现细节。‌

3.2 多个产品系列配置

如果一个系统需要由多个产品系列中的一个来配置,‌抽象工厂模式可以提供一个统一的接口来创建这些产品系列中的对象,‌确保系统的一致性和可维护性。‌

3.3 强调一系列相关的产品对象设计

当需要强调一系列相关的产品对象的设计以便进行联合使用时,‌抽象工厂模式可以确保这些对象一起被正确地创建和使用,‌以满足特定的功能需求。‌

3.4 提供产品类库的接口而非实现:

如果提供一个产品类库,‌而只想显示它们的接口而不是实现时,‌抽象工厂模式可以通过提供一个统一的接口来创建这些产品对象,‌使得客户端代码不依赖于具体的实现细节,‌增加了系统的灵活性和可扩展性。‌

4. 抽象工厂的代码示例介绍

在这里插入图片描述
我们将针对此图进行编程,着重介绍抽象工厂模式。

4.1 抽象工厂设计模式超类和子类

4.1.1 Computer.java

public abstract class Computer {public abstract String getRAM();public abstract String getHDD();public abstract String getCPU();@Overridepublic String toString(){return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();}
}

4.1.2 PC.java

public class PC extends Computer {private String ram;private String hdd;private String cpu;public PC(String ram, String hdd, String cpu){this.ram=ram;this.hdd=hdd;this.cpu=cpu;}@Overridepublic String getRAM() {return this.ram;}@Overridepublic String getHDD() {return this.hdd;}@Overridepublic String getCPU() {return this.cpu;}}

4.1.3 Server.java

public class Server extends Computer {private String ram;private String hdd;private String cpu;public Server(String ram, String hdd, String cpu){this.ram=ram;this.hdd=hdd;this.cpu=cpu;}@Overridepublic String getRAM() {return this.ram;}@Overridepublic String getHDD() {return this.hdd;}@Overridepublic String getCPU() {return this.cpu;}}

4.2 编写每个子类的工厂类

首先我们需要创建一个抽象工厂接口或抽象类,如上图这个抽象给抽象工厂类叫ComputerAbstractFactory.java

public interface ComputerAbstractFactory {public Computer createComputer();
}

注意该createComputer()方法返回的是超类的一个实例Computer。现在我们的工厂类将实现此接口并返回各自的子类。

4.2.1 PCFactory.java

public class PCFactory implements ComputerAbstractFactory {private String ram;private String hdd;private String cpu;public PCFactory(String ram, String hdd, String cpu){this.ram=ram;this.hdd=hdd;this.cpu=cpu;}@Overridepublic Computer createComputer() {return new PC(ram,hdd,cpu);}
}

类似地,我们将有一个用于Server子类的工厂类。ServerFactory.java

4.2.2 ServerFactory.java

public class ServerFactory implements ComputerAbstractFactory {private String ram;private String hdd;private String cpu;public ServerFactory(String ram, String hdd, String cpu){this.ram=ram;this.hdd=hdd;this.cpu=cpu;}@Overridepublic Computer createComputer() {return new Server(ram,hdd,cpu);}
}

现在我们将创建一个消费者类,为客户端类创建子类提供入口点。ComputerFactory.java

public class ComputerFactory {public static Computer getComputer(ComputerAbstractFactory factory){return factory.createComputer();}
}

注意,它是一个简单的类,getComputer方法接受ComputerAbstractFactory参数并返回Computer对象。此时实现应该已经很清晰了。

让我们编写一个简单的测试方法,看看如何使用抽象工厂来获取子类的实例。TestDesignPatterns.java

public class TestDesignPatterns {public static void main(String[] args) {testAbstractFactory();}private static void testAbstractFactory() {Computer pc = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));Computer server = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new ServerFactory("16 GB","1 TB","2.9 GHz"));System.out.println("AbstractFactory PC Config::"+pc);System.out.println("AbstractFactory Server Config::"+server);}
}

上述程序的输出将是:

AbstractFactory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
AbstractFactory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz

5. 抽象工厂模式优缺点

抽象工厂模式的优点包括封装性解耦性、‌产品族一致性、‌易于替换扩展、‌提高系统灵活性,‌而缺点则包括复杂性增加、‌不易于新增产品、‌不支持单一产品的变化。‌

5.1 抽象工厂模式优点

5.1.1 封装性和解耦性:

抽象工厂模式将对象的创建和使用分离,‌客户端代码不需要关心具体的产品类,‌从而实现了解耦。‌客户端代码只需要依赖抽象工厂接口,‌而不依赖具体产品。‌

5.1.2 产品族一致性

抽象工厂模式确保一组相关或依赖的产品能够协同工作,‌因为每个具体工厂类都会创建一整套相关产品。‌这有助于保持产品之间的一致性。‌

5.1.3 易于替换和扩展

通过添加新的具体工厂类和产品类,‌可以轻松扩展抽象工厂模式,‌而不需要修改现有的客户端代码。‌这使得系统更易于维护和扩展。‌

5.1.4 提高系统灵活性

抽象工厂模式允许在运行时切换不同的具体工厂,‌从而使应用程序更容易适应不同的配置或环境,‌提高了系统的灵活性。‌

5.2 抽象工厂模式缺点

5.2.1 复杂性增加:

抽象工厂模式引入了多个抽象类和接口,‌以及多个具体工厂和产品类,‌因此可能会增加系统的复杂性。‌对于小规模应用程序或简单的需求,‌可能显得过于繁琐。‌

5.2.2 不易于新增产品

如果需要新增一种产品,‌抽象工厂模式的修改会比较复杂,‌因为需要同时修改抽象工厂接口和所有具体工厂类。‌这可能会导致修改的传播,‌影响到现有的代码。‌

5.2.3 不支持单一产品的变化

抽象工厂模式适用于一组相关产品的创建,‌但如果只有一个产品发生变化,‌那么整个工厂都需要进行修改,‌可能不够灵活。‌

5.3 抽象工厂模式优缺点总结

总的来说,‌抽象工厂模式适用于需要创建一组相关产品,‌同时具备高度灵活性和可维护性的场景。‌

6. JDK 中的抽象工厂设计模式示例

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

7. 总结

抽象工厂模式是一种设计模式,‌它属于创建型模式,‌主要用于构建产品族。‌这种模式当有多个抽象角色时使用,‌向客户端提供一个接口,‌使得客户端在不必指定产品的具体情况下,‌能够创建多个产品族中的产品对象。‌抽象工厂模式是所有工厂模式中最抽象和最具一般性的一种形态,‌它针对的是多个产品族结构,‌而不是单个产品系列结构。‌

在抽象工厂模式中,‌每一个工厂负责创建一个产品族,‌而不是单个产品。‌这与工厂方法模式不同,‌后者是针对单个产品系列的。‌抽象工厂模式的实现原理包括将一组相关或相互依赖的对象抽象成产品族,‌每个工厂负责创建一个产品族。‌这种模式允许在不修改客户端代码的情况下增加新的产品族,‌同时保持了代码的灵活性和可扩展性。‌

抽象工厂模式的角色包括:‌

  1. 抽象产品:‌定义了产品的规范和接口。‌
  2. 具体产品:‌实现了抽象产品的接口,‌是实际的产品对象。‌
  3. 抽象工厂:‌提供了创建产品的接口,‌但不负责实现这些接口。‌

抽象工厂模式的优点包括:‌

  1. 灵活性:‌可以轻松扩展新的工厂类,‌支持新的主题或对象类型。‌
  2. 可维护性:‌将对象的创建与使用分离,‌使代码更清晰、‌易于维护。‌
  3. 可靠性:‌避免对象的不正确创建和使用,‌提高代码可靠性。‌

然而,‌抽象工厂模式也存在一些缺点,‌例如不利于添加新种类产品,‌因为每增加一个新产品种类可能需要修改现有的工厂类,‌这违反了开闭原则。‌

相关文章:

Java设计模式-抽象工厂模式-一次性理解透

1. 抽象工厂模式简介 抽象工厂设计模式是创建型模式之一。抽象工厂模式与工厂模式几乎相似,只是它更像工厂中的工厂。 如果您熟悉Java 中的工厂设计模式,或看过上一篇我写的“java简单工厂模式”,您会注意到我们有一个工厂类。此工厂类根据…...

day16-测试自动化之selenium的PO模式

一、PO模式介绍 PO(Page Object)模式是一种在自动化测试中常用的设计模式,将页面的每个元素封装成一个对象,通过操作对象来进行页面的交互。 一般分为六个版本,现在大部分企业都用的V4版本,三层结构…...

Springboot+freemarker大段文本内容动态修改输出,所见即所得

场景:给领导导出数据时,需要给出一个针对专业名词的解释说明,因此会存在有大批量的、大段的文本内容。如果直接写在代码里面,没啥大问题,但是大量的拼接替换、格式样式、后续修改维护等,都不是很方便。如果…...

Kali Linux网络问题解决与静态IP配置技巧

很多用户在使用 Kali Linux 时会遇到无法联网的问题,尤其是在 VMware 虚拟机中。这种情况相当常见,一般都是没有配置DNS服务器或者网卡配置文件的IP和虚拟网络编辑器的IP不一致所导致的,下面我们将探讨如何在 Kali Linux 中配置 DNS 服务和设…...

网络状态码-经验笔记

网络状态码-经验笔记 引言 在网络通信中,HTTP(Hypertext Transfer Protocol)状态码是服务器向客户端(通常是Web浏览器)发送响应时所包含的重要信息之一。 这些状态码指示了客户端请求的结果。 了解并正确使用这些状态…...

c++ 实现 actor 框架

服务端:https://github.com/xukeawsl/coro_actor 客户端:https://github.com/xukeawsl/coro_actor_client...

应对猫咪掉毛挑战,希喂、小米热门宠物空气净化器实测功效PK

随着养宠人群的增多,铲屎官们的需求日益增长,市场上出现了很多品牌的宠物空气净化器。然而,产品质量参差不齐,给消费者选择带来不少困难。劣质宠物空气净化器不仅无法有效去除宠物毛发、皮屑、异味及空气中的有害微粒,…...

0002 保险会计及其特殊性

保险会计是将会计理论专门应用于保险公司的专业会计领域,它是会计学的一个重要分支。作为一个分支,保险会计具有独特的特性,这些特性主要表现在以下几个方面: 产品的无形性:保险产品本质上是一种无形的商品&#xff0c…...

ChatTTS:终极文本转语音工具,支持API!

ChatTTS:终极文本转语音工具,支持API! 文本转语音(TTS)系统的发展已经取得了长足的进步。从最初的机械化、平坦的声音,到如今听起来令人惊讶的人声,ChatTTS作为这一领域的新成员,旨…...

VUE和Element Plus

1.VUE 1.下载和配置环境 使用vue编程,我们需要使用到的编程软件是vs code,还需要使用node.js,这个的作用就类似于JDK,当我们都下载好之后,winR键打开命令提示符,我们在这里可以查看版本, npm…...

Python学习笔记(五)

""" 演示tuple元组的定义和操作 """# 元组一旦定义完成,就不可修改 # 定义元组 # t1 (1, "Hello", True) # t2 () # 定义空元组 # t3 tuple() #定义空元组 # print(f"t1的类型是:{type(t1)}, 内容是&…...

Linux企业级应用(一)构建企业级Linux应用平台:全面指南

文章目录 构建企业级Linux应用平台:全面指南前言1. Linux企业级应用简介2. 构建企业级网站应用平台使用LNMP架构构建Web服务器部署MySQL数据库主从复制与读写分离 3. 实施虚拟化技术部署KVM虚拟化平台使用LVS和Keepalived实现负载均衡与高可用性 4. 文件系统与分布式…...

LeetCode112 路径总和

前言 题目: 112. 路径总和 文档: 代码随想录——路径总和 编程语言: C 解题状态: 成功解答! 思路 比较简单的一个思路是遍历所有的路径,求和后再查找目标值。但是,最好的方法是一边遍历&#x…...

TI AWR1843 毫米波雷达实物展示

引言 随着自动驾驶、工业自动化以及智能交通系统的快速发展,雷达传感器在现代科技中的重要性日益提升。毫米波雷达凭借其高精度测距、抗干扰能力强等特点,逐渐成为各类感知系统中的关键技术。德州仪器(TI)推出的 AWR1843 毫米波雷…...

前端JS总结(下)之事件操作

目录 前言 事件基础 事件的三部分: 常见的事件: 鼠标事件: 键盘事件: 表单事件: onfocus和onblur:获取焦点和失去焦点 onselect:选中单行文本框/多行文本框中的内容 onchange&#xff…...

如何妙用哈希表来优化遍历查找过程?刷题感悟总结,c++实现

先上题目 题目链接:题目链接 这题我最先想到的就是前缀和a,构造好了以后就遍历每一个[l,r]数组(满足题目要求的连续区间数组),奈何倒数第二个样例时间超限 先给出原思路代码 class Solution { public:int subarray…...

【设计模式】漫谈设计模式

这篇文章里说一下对设计模式的个人的理解。本篇文章更类似于随笔而非技术文档。 设计模式最早是在上个世纪就被人提出来了,如今被奉为圣经,也就是GOF等人写的《设计模式》,其中的设计模式,是指导开发者如何进行开发出高内聚、低耦…...

第N5周:Pytorch文本分类入门

本文为365天深度学习训练营 中的学习记录博客原作者:K同学啊 任务: ●1. 了解文本分类的基本流程 ●2. 学习常用数据清洗方法 ●3. 学习如何使用jieba实现英文分词 ●4. 学习如何构建文本向量 一、前期准备 环境安装 这是一个使用PyTorch实现的简单文…...

SpringBoot 自定义 starter

1. 官方文档 SpringBoot 版本 2.6.13,相关链接 Developing with Spring Boot 1.1 什么是 Starter Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and relate…...

TDengine Invalid data format 问题定位

Invalid data format 看语义是数据类型不符,通常这个报错出现在使用行协议写入时。 如果是批量数据写入,想定位是哪条语句的问题,需要查看客户端日志。 如何确定使用的是哪个日志 lsof -p pidof taosadapter | grep taoslog如果没有安装lso…...

时序逻辑与值函数分解在强化学习中的应用

1. 时序逻辑与值函数分解的核心原理 时序逻辑(Temporal Logic, TL)作为形式化方法的重要分支,其本质是通过数学语言描述系统在时间维度上的行为约束。在控制理论与强化学习领域,TL的价值在于将复杂的任务需求转化为可计算的优化目…...

TalkReplay:构建本地化AI编程对话时光机,实现知识持久化管理

1. 项目概述:一个为AI编程对话而生的“时光机”如果你和我一样,日常开发已经离不开Claude、Cursor这类AI编程助手,那你一定遇到过这个痛点:和AI进行了一下午的深度对话,写了几百行代码,解决了几个关键问题。…...

基于星座匹配的眼动追踪角膜反射检测技术解析

1. 项目概述:基于星座匹配的角膜反射检测框架在眼动追踪技术领域,瞳孔-角膜反射(P-CR)方法一直是最可靠的解决方案之一。这种方法的核心在于准确检测和匹配角膜反射点(glints)——即红外LED在角膜表面形成的…...

轻量级Web代理moltron:架构解析与生产级部署实战

1. 项目概述:一个轻量级、高性能的Web代理工具在开发和运维的日常工作中,我们经常需要处理不同网络环境下的服务访问问题。比如,本地开发需要调试一个部署在内网测试环境的API,或者需要安全地访问某些仅限特定网络访问的资源。传统…...

Anthropic研究院议程:不止做AI大模型,更要定义AI时代的全球规则

当大模型竞赛进入白热化,多数科技公司都在比拼参数、速度、模型能力时,OpenAI竞品Anthropic走出了一条完全不同的路。 近期,Anthropic 正式公布 Anthropic Institute(Anthropic研究院)全新研究议程,不再只埋头做模型研发,而是站在行业顶层视角,深度拆解AI对经济、安全、…...

【2026最硬核LLM加速框架】:仅用7行Triton内核重写Attention,吞吐翻3.2倍——SITS现场调试录屏首曝

更多请点击: https://intelliparadigm.com 第一章:AI原生性能优化:SITS 2026 LLM推理加速实战技巧 在 SITS 2026 基准测试中,LLM 推理延迟与显存带宽利用率高度相关。AI 原生优化强调从计算图调度、内核融合到硬件亲和性配置的端…...

RPGMZ 战斗结束 移除死亡的角色 并且显示一个消息框 然后结束战斗

个人记录保存 Project1论坛 小圈子 人才 不得学习我的技术 1. BattleManager.endBattle 不论是战斗失败 胜利 逃跑 都会走这个敌方 我们在这里显示我们的消息框 下面这段代码就是战斗结束 移除死亡的队员 并且显示一个消息框的代码功能 经过测试有效 const _BattleManager_…...

Rust Cargo工作空间:项目组织与依赖管理

Rust Cargo工作空间:项目组织与依赖管理 引言 Cargo是Rust的官方构建工具和包管理器。工作空间(Workspace)是Cargo的重要特性,允许将多个相关的crate组织在一起,共享依赖和配置。 本文将深入探讨Cargo工作空间的使用方法、最佳实践和高级配置…...

Diablo Edit2完全手册:开源角色编辑器的深度解析

Diablo Edit2完全手册:开源角色编辑器的深度解析 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 你是否曾在暗黑破坏神2中花费数小时刷装备,只为获得一件特定属性的装备&am…...

打破语言壁垒:Translumo屏幕实时翻译工具的终极使用指南

打破语言壁垒:Translumo屏幕实时翻译工具的终极使用指南 【免费下载链接】Translumo Advanced real-time screen translator for games, hardcoded subtitles in videos, static text and etc. 项目地址: https://gitcode.com/gh_mirrors/tr/Translumo 你是否…...