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.mfbz.cn/a/573808.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pytest数据驱动DDT

常见的DDT技术 数据结构: 列表、字典、json串 文件: txt、csv、xcel 数据库: 数据库链接 数据库提取 参数化: pytest.mark.parametrize() pytest.fixture() D…

【课程发布】软考高项目十大管理ITTO宫殿记忆法新版第四版正式发布

软考高项十大管理ITTO宫殿记忆法视频课程: 平台:荔枝微课 连接:十方教育 各位软考高级信息系统项目管理师考生好,新版第四版十大管理ITTO宫殿记忆法视频课程终于发布了,之前苦等的考生终于迎来了救星,再也…

OAuth2、JWT

文章目录 OAuth2JWT OAuth2 官网: https://oauth.net/2/ 在 RFC 6749 中说明 1、资源所有者 resource owner, 如 github 用户 2、客户端/第三方应用 client, 如 支持github 登录的 csdn 3、资源服务器 resource server, 如 4、授…

【C/C++笔试练习】OSI分层模型、源端口和目的端口、网段地址、SNMP、状态码、tcp报文、域名解析、HTTP协议、计算机网络、美国节日、分解因数

文章目录 C/C笔试练习选择部分(1)OSI分层模型(2)源端口和目的端口(3)网段地址(4)SNMP(5)状态码(6)tcp报文(7)域…

GRASSHOPPER电池Expression

Grasshopper中如果要实现简单的条件if语句的效果,可以使用电池Expression。 举例:获取两个数的差值,永远用大数减去小数

Geoserver中点击切片图层报错问题

最近想试试wmts,其中有一步需要用到切片图层 但是点击页面老是报错, 于是乎想断点,可惜代码太复杂 弃了,所以想重新部署一下新版本,结果还是报错,想着可能tomcat有缓存吧,在换个tomcat还是报错…

《QT实用小工具·四十二》圆形发光图像

1、概述 源码放在文章末尾 该项目实现了图像的发光效果,特别适合做头像,项目demo演示如下所示: 项目部分代码如下所示: import QtQuick 2.7 import QtGraphicalEffects 1.12Item {id: rootwidth: 80height: 80property int ra…

【JVM】java内存区域

目录 一、运行时数据区域 1、方法区 2、堆 3、虚拟机栈 4、本地方法栈 5、程序计数器 6、运行时常量池 二、HotSpot虚拟机的对象 1、对象的创建 指针碰撞: 空闲列表: 2、对象的内存布局 对象头 实例数据 对齐填充 3、对象的访问定位 句…

一种基于 RFID 技术的养老院人员定位解决方案

在今日的中国社会结构老龄化日趋增长,带来了一系列的社会问题。社会老龄化、高龄化、空巢化和病残化的迅速发展,将使得越来越多的老人住进养老院。养老院主要为老人提供集体居住,并具有相对完整的配套服务设施。养老院管理的最终目的就是为老…

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Combo Box的使用及说明

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt常用控件 | 输入类控件 | Combo Box的使用及说明 文章编号&#xff…

张大哥笔记:普通人如何搞钱?

追求短期利润和长期价值相结合的创业方式,是我一直倡导的。短期内寻求盈利的项目进行快速变现,比如各种小风口项目,而长期项目则需保持数年乃至10年不变,比如自媒体内容输出,做有长期价值的事情! 短期项目通…

详解MySQL C API 相关接口(大白话就是:MySQL的c语言怎么写)

文章目录 1、C API 官方文档2、初始化 MYSQL3、连接 MySQL设置连接字符集(使得客户端编码方式匹配) 4、下发 mysql 指令5、获取 mysql 查询结果(保存起来)获取行与列遍历存储结果 6、释放 MYSQL\_RES 对象7、关闭 MySQL 连接8、总结 1、C API 官方文档 …

Linux安装Docker的多版本PHP和多版本MySQL共存

1: 先安装docker 安装完后执行,权限设置 sudo usermod -aG docker $USER或者sudo usermod -aG docker kentrl#添加当前用户到Docker用户组中 sudo newgrp docker#更新用户组数据,必须执行否则无效 sudo systemctl restart docker 先看目录结构: 2:按照目录结构挂载磁盘,…

(一)Amira入门实例

1.打开Amira安装目录下的数据Foam.am图片,打开之后选择“um”选项。 2. 添加一个2D和3D显示组件,即Ortho Slice和Volume Rendering,分别为2D显示和3D显示(模块左侧绿点控制是否显示): 颜色反转之后&#xf…

C# GetField 方法应用实例

目录 关于 C# Type 类 GetField 方法应用 应用举例 心理CT设计题 类设计 DPCT类实现代码 小结 关于 C# Type 类 Type表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。调用 t…

第十五届蓝桥杯省赛第二场C/C++B组G题【最强小队】题解

20pts 枚举所有可能的左端点、右端点,时间复杂度 O ( n 2 ) O(n^2) O(n2)。 对于每个区间进行遍历检测,时间复杂度 O ( n 3 ) O(n^3) O(n3)。 100pts 由于数据范围为 1 0 5 10^5 105,所以肯定只能进行一次枚举。 我们尝试枚举右端点&…

winform实现的调用bartender打印工具-标签模版管理

生产型企业基本都有条码追溯管理的需求&#xff0c;不同的产品有不同的标签样式规格以及内容&#xff0c;打印的条码往往需要追溯以及防重校验&#xff0c;因此市面有很多打印软件&#xff0c;今天分享基于winform开发的调用bartender标签的工具。 先上效果图 /// <summary…

软考 - 系统架构设计师 - 设计模式

目录 概念 创建型设计模式 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09; 优点 缺点 应用场景 总结 构建器模式&#xff08;Builder Pattern&#xff09; 优点 缺点 应用场景 工厂方法模式&#xff08;factory method&#xff09; 优点 缺点 应…

AES 加解密(包含JS、VUE、JAVA、MySQL)工具方法

介绍 AES 是 Advanced Encryption Standard 的缩写&#xff0c;是最常见的对称加密算法。AES 在密码学中又称 Rijndael 加密法&#xff0c;是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES&#xff0c;已经被多方分析且广为全世界所使用。 基本原理&#…

3.8设计模式——State 状态模式(行为型)

意图 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 结构 Context&#xff08;上下文&#xff09;定义客户感兴趣的接口&#xff1b;维护一个ConcreteState子类的实例&#xff0c;这个实例定义当前状态。State&#xff08;状态&#xff09;定义…
最新文章