Java基础:设计模式之抽象工厂模式

一、模式定义与目的

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它为创建一组相关或相互依赖的对象提供了接口,而无需指定这些对象的具体类。这种模式允许客户端使用抽象接口来创建家族内的产品对象,而不必关心实际创建产品的具体细节。抽象工厂模式的核心在于定义一个包含多个创建方法的抽象工厂接口或抽象类,每个方法用于生成产品族中的一个特定产品。

二、模式结构

抽象工厂模式涉及以下主要角色:

  1. AbstractFactory(抽象工厂):定义创建一系列相关或相互依赖对象的接口。它声明了一组创建不同产品的方法,这些方法通常对应于一个产品等级结构。

  2. ConcreteFactory(具体工厂):实现了抽象工厂接口,负责生成一个或多个具体产品。每个具体工厂对应于一种产品族。

  3. Product(产品接口/抽象类):定义了产品对象的接口,它是相关产品对象的共同父接口(或抽象类)。可以有一个或多个产品等级结构。

  4. ConcreteProduct(具体产品):实现了产品接口,由具体工厂创建,代表了某一具体类型的产品。

三、示例说明

假设有一个图形应用程序,需要绘制不同操作系统(如Windows、MacOS)上的图形元素,包括圆形(Circle)和方形(Square)。每个操作系统都有自己的图形实现,它们具有不同的外观和行为。为了隔离操作系统差异,我们可以使用抽象工厂模式来设计。

// 产品接口(产品等级结构)
interface Shape {void draw();
}class Circle implements Shape {public void draw() { /* 绘制圆形的逻辑 */ }
}class Square implements Shape {public void draw() { /* 绘制方形的逻辑 */ }
}// 抽象工厂
interface GraphicFactory {Shape createCircle();Shape createSquare();
}// 具体工厂
class WindowsGraphicFactory implements GraphicFactory {public Circle createCircle() { return new WindowsCircle(); }public Square createSquare() { return new WindowsSquare(); }
}class MacOSGraphicFactory implements GraphicFactory {public Circle createCircle() { return new MacOSCircle(); }public Square createSquare() { return new MacOSSquare(); }
}// 具体产品(Windows/MacOS 版本的图形)
class WindowsCircle extends Circle { /* 特定于Windows的实现 */ }
class WindowsSquare extends Square { /* 特定于Windows的实现 */ }class MacOSCircle extends Circle { /* 特定于MacOS的实现 */ }
class MacOSSquare extends Square { /* 特定于MacOS的实现 */ }// 客户端代码
public class Client {public static void main(String[] args) {GraphicFactory factory;if (isRunningOnWindows()) {factory = new WindowsGraphicFactory();} else {factory = new MacOSGraphicFactory();}Shape circle = factory.createCircle();Shape square = factory.createSquare();circle.draw();square.draw();}
}

在这个例子中,Shape 是产品接口,CircleSquare 是具体产品。GraphicFactory 是抽象工厂,它定义了创建两种形状的方法。WindowsGraphicFactoryMacOSGraphicFactory 是具体工厂,它们实现了抽象工厂接口,根据操作系统创建相应的图形对象。客户端代码仅与抽象工厂接口交互,从而实现了跨平台绘图功能,无需知道具体操作系统环境下图形对象的实现细节。

四、存在的问题

尽管抽象工厂模式提供了良好的灵活性和封装性,但它也存在一些问题:

  1. 增加新的产品等级结构困难:如果需要增加一个新的产品族(例如,添加三角形),不仅需要修改抽象工厂接口(新增创建三角形的方法),还需要修改所有具体工厂类以实现新方法,这违背了“开闭原则”,即对扩展开放,对修改关闭。

  2. 系统复杂度增加:由于抽象工厂模式涉及多个产品等级结构和工厂类,随着产品种类和操作系统的增多,类的数量和系统复杂度会迅速增长,可能导致代码难以理解和维护。

  3. 依赖于抽象:客户端依赖于抽象工厂接口,虽然降低了对具体实现的依赖,但如果抽象工厂接口设计得过于复杂或不够通用,可能会限制客户端的灵活性。

  4. 适应需求变化困难:当产品族内部结构发生变化时,可能需要调整抽象工厂和具体工厂的实现,以及客户端代码。特别是当产品族之间的关系变得复杂时,这种调整可能会非常困难。

  5. 不易于切换产品系列:如果要在一个运行时环境中动态地切换产品系列(例如,从Windows风格图形切换到MacOS风格),可能需要重新创建工厂对象,这在某些情况下可能不切实际或难以实现。

综上所述,抽象工厂模式适用于需要创建一组相关或相互依赖对象,且客户端不希望直接与这些对象的具体类打交道的情况。它提供了较好的封装性和灵活性,但同时也带来了较高的复杂度和对扩展的倾斜性,需要在实际项目中权衡使用。在面对产品族变动频繁、系统复杂度要求较高的场景时,可能需要考虑其他设计策略或结合使用其他设计模式来缓解这些问题。

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

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

相关文章

Yolov5 export.py实现onnx模型的导出

查了很多资料,很多用python代码写的,只需要这个库那个库的,最后都没成功。 不如直接使用Yolov5里面的 export.py实现模型的转换。 一:安装依赖 因为yolov5里面的requirments.txt是将这些转换模型的都注释掉了 所以需要解除注释…

SAP如何批量标记生产订单的TECO状态

声明:本文仅代表作者观点和立场,不代表任何公司!仅用于SAP软件应用学习参考。 SAP/ERP系统生产订单完工后,在进行结算之前,需要进行技术性完成操作,即将生产订单批量标记TECO,标记上TECO表示生…

独立站运营教程:站外引流如何做?

在当今全球化的商业环境中,跨境电商已经成为一个蓬勃发展的行业。对于跨境电商独立站来说,站外引流是非常关键的一环,它可以帮助独立站吸引更多潜在客户,提升品牌知名度,促进销售增长。本文将深入探讨如何实现跨境电商…

eNSP学习——静态路由及默认路由基本配置

目录 知识背景 实验目的 实验步骤 实验内容 实验拓扑 实验编址 实验前期准备 实验步骤 1、基本配置(按照实验编址设置好对应的IP地址) 2、是实现主机之间的通信 3、实现全网全通来增强网络的可靠性 4、使用默认路由实现简单的网络优化 需要各…

【静态分析】静态分析笔记07 - 指针分析基础

参考: 【课程笔记】南大软件分析课程7——指针分析基础(课时9/10) - 简书 -------------------------------------------------------------- 1. 指针分析规则 规则:采用推导形式,横线上面是条件,横线下…

MySQL--表的操作

目录 创建表 查看表结构 修改表 新增列 修改列类型 修改列名 修改表名: 删除列 删除表 创建表 语法: CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引…

【论文阅读】Self-DC:何时检索,何时生成?

对于RAG来说,什么时候利用外部检索,什么时候使用大模型产生已知的知识,以回答当前的问题?这是一个非常有趣的话题。 《Self-DC: When to retrieve and When to generate? Self Divide-and-Conquer for Compositional Unknown Questions》这…

【设计模式】12、observer 观察者模式

文章目录 十二、observer 观察者模式12.1 subscriber12.1.1 broker_test.go12.2.2 broker.go12.2.3 client.go 十二、observer 观察者模式 https://refactoringguru.cn/design-patterns/observer 发布订阅模式, client 都可以向 broker 注册, broker 管理所有 connection, 当…

MySQL尾部空格处理与哪些设置有关? 字符集PAD SPACE与NO PAD属性的区别、MySQL字段尾部有空格为什么也能查询出来?

文章目录 一、问题背景二、字符集PAD_ATTRIBUTE属性(补齐属性)2.2、PAD SPACE与NO PAD的具体意义 三、CHAR类型尾部空格的处理四、其他问题4.1、在PAD SPACE属性时如何实现精准查询 五、总结 以下内容基于MySQL8.0进行讲解 一、问题背景 一次查询中发现…

Threejs加载字体加载FontLoader与TTFLoader

在 Three.js 中使用自定义字体进行 3D 文本渲染。它最初是以 JSON 格式加载字体,现在Three.js已经有一个 TTFLoader 类,可用于加载 TTF 字体文件并将它们用作 TextGeometry ! 1、最初使用FontLoader加载json字体方法如下 const loader new…

NVIDIA CUDA Toolkit

NVIDIA CUDA Toolkit CUDA Toolkit 12.4 Update 1 Downloads | NVIDIA Developer CUDA Toolkit是用于CUDA开发的软件包,主要包括CUDA编译器、运行时库、GPU驱动程序和开发工具等。它允许开发者使用通用编程语言(如C、C)来利用NVIDIA GPU进行…

ZDOCK linux 下载(无需安装)、配置、使用

ZDOCK 下载 使用 1. 下载1)教育邮箱提交申请,会收到下载密码2)选择相应的版本3)解压 2. 使用方法Step 1:将pdb文件处理为ZDOCK可接受格式Step 2:DockingStep 3:创建所有预测结构 1. 下载 1&…

2023平航杯——介质取证部分复现

闻早起的电脑 教徒“闻早起”所使用的笔记本电脑使用何种加密程式? VeraCrypt 教徒“闻早起”所使用的笔记本电脑中安装了一款还原软件,其版本号为?【标准格式:1.2.3.4】 8.71.020.5734 教徒“闻早起”所使用的笔记本电脑中登…

.gitignore语法及配置问题

语法及配置 前言.gitignore语法Git 忽略规则优先级gitignore规则不生效Java项目中常用的.gitignore文件c项目中常用的.gitignore注意事项 前言 在工程中,并不是所有文件都需要保存到版本库中,例如“target”目录及目录下的文件就可以忽略。在Git工作区的…

CSS中的 5 类常见伪元素详解!

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生,一枚程序媛,感谢关注。回复 “前端基础题”,可免费获得前端基础 100 题汇总,回复 “前端工具”,可获取 Web 开发工具合…

使用python setup.py报错:Upload failed (403) / Upload failed (400)

当前报错的环境 Python 3.9.19twine1.15.0 本地~/.pypirc已正确配置了用户名和密码,用在pypi.org注册: [pypi]username skylerhupassword ${password}执行 python setup.py sdist upload -r pypi 打包上传到仓库报错。 在不久之前同样的环境&#…

2018-2023年上市公司富时罗素ESG评分数据

2018-2023年上市公司富时罗素ESG评分数据 1、时间:2018-2023年 2、来源:整理自WIND 3、指标:证券代码、简称、ESG评分 4、范围:上市公司 5、指标解释: 富时罗素将公司绿色收入的界定和计算作为公司ESG 评级打分结…

macbook m1 nacos集群启动失败报错的解决办法

问题来源:(黑马springcloud学习过程)P29-06-Nacos配置管理-nacos集群搭建 问题描述:详情见nacos.log和start.out WebServerException: Unable to start embedded Tomcat (mach-o file, but is an incompatible architecture (have ‘x86_64’, need ‘a…

记录如何用php将敏感文字内容替换为星号的方法

在PHP中&#xff0c;将敏感文字用星号替换通常涉及到字符串的搜索和替换操作。你可以使用PHP的内置函数str_replace()来实现这个功能。下面是一个基本的示例&#xff0c;展示如何将特定的敏感词替换为星号&#xff1a; <?php // 要检查的原始文本 $text "这个文本包…

什么是DTU和串口服务器的区别

在工业物联网的快速发展中&#xff0c;数据传输单元&#xff08;DTU&#xff09;和串口服务器作为两种关键设备&#xff0c;各自扮演着重要的角色。对于传统行业来说&#xff0c;了解它们的基本概念和区别&#xff0c;有助于更好地选择和应用这些技术&#xff0c;提升生产效率和…