抽象工厂

抽象工厂设计模式是一种创建模式,它提供了一个用于创建相关或从属对象族的接口,而无需指定其具体类。
它在以下情况下特别有用:
您需要创建必须一起使用并且是一致系列的一部分的对象(例如,按钮、复选框和菜单等 GUI 元素)。
您的系统必须支持多种配置、环境或产品变体(例如,浅色与深色主题、Windows 与 macOS 外观)。

您希望在相关对象之间强制保持一致性,确保它们都是从同一个工厂创建的。
抽象工厂模式将 对象创建封装到工厂接口中。

每个具体工厂实现接口并生成一组完整的相关对象。这可确保您的代码保持可扩展、一致并与特定产品实现松散耦合。
让我们通过一个真实世界的示例,看看如何应用抽象工厂模式来构建一个灵活、可维护的系统,并且能够在没有条件逻辑的情况下支持多个可互换的产品系列。

问题:特定于平台的 UI
假设你正在构建一个必须同时支持 Windows 和 macOS 的跨平台桌面应用程序。

为了提供良好的用户体验,您的应用程序应 为每个作系统呈现具有本机外观的 UI 组件,例如:

按钮
复选框
文本字段
菜单
朴素实现:条件 UI 组件实例化
在第一次尝试中,您可以实现特定于平台的 UI 组件,如下所示:
Windows UI 元素

  public class WindowsButton implements Button {@Overridepublic void paint() {System.out.println("Painting a Windows-style button.");}@Overridepublic void onClick() {System.out.println("Windows button clicked.");}
}public class WindowsCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Painting a Windows-style checkbox.");}@Overridepublic void onSelect() {System.out.println("Windows checkbox selected.");}
}

MacOS UI元素

public class MacOSButton implements Button {@Overridepublic void paint() {System.out.println("Painting a macOS-style button.");}@Overridepublic void onClick() {System.out.println("MacOS button clicked.");}
}public class MacOSCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Painting a macOS-style checkbox.");}@Overridepublic void onSelect() {System.out.println("MacOS checkbox selected.");}
}

然后,在应用程序逻辑中,您最终会执行以下作:

public class App {public static void main(String[] args) {String os = System.getProperty("os.name");if (os.contains("Windows")) {WindowsButton button = new WindowsButton();WindowsCheckbox checkbox = new WindowsCheckbox();button.paint();checkbox.paint();} else if (os.contains("Mac")) {MacOSButton button = new MacOSButton();MacOSCheckbox checkbox = new MacOSCheckbox();button.paint();checkbox.paint();}}
}

为什么这种方法会失败
虽然此设置适用于两个平台上的两个 UI 组件,但随着应用的增长,它很快就会成为一场噩梦。

  1. 1. 与混凝土类紧密耦合
    您的主应用程序逻辑与特定于平台的类 (, , 等) 紧密绑定。这意味着无论在何处创建 UI 组件,都必须手动检查作系统。WindowsButtonMacOSCheckbox
  2. 2. 无抽象或多态性
    不能笼统地处理按钮或复选框。没有像或可以使用的通用界面 。ButtonCheckbox
  3. 3. 代码重复和重复
    每个特定于平台的块都复制了类似的逻辑——实例化按钮、复选框、菜单等。你将在整个代码库中重复此条件分支。
  4. 4. 可扩展性问题
    当您:

添加新平台(例如 Linux)?

添加新组件(例如,、、)?TextFieldSliderMenuBar

您必须:

为每个平台添加新的具体类

修改代码中出现特定于平台的逻辑的每个位置

破坏现有行为的风险

  1. 5. 违反开放/关闭原则
    任何新的变体都需要修改现有代码。您的 UI 创建逻辑不开放扩展,但对重大更改非常开放。

我们真正需要什么
我们需要一种方法来:

按平台对相关组件(按钮、复选框等)进行分组

将特定于平台的创建逻辑封装到工厂中

以多态方式处理 UI 组件,无论平台如何

轻松添加新的 UI 元素系列,而无需修改应用程序的核心逻辑

这就是抽象工厂模式的用武之地。

抽象工厂模式
抽象工厂模式提供了一个接口,用于创建相关或依赖对象的族,而无需指定其具体类。

在我们的例子中,我们想要创建一个 UI 组件系列(如 、 、 等),这些组件在不同平台(例如 Windows 或 macOS)上的外观和行为不同,但向应用程序公开相同的界面。ButtonCheckboxTextField

抽象工厂模式通过以下方式帮助我们实现这一目标:

定义抽象 UI 工厂接口(例如 GUIFactory)

为每个平台实施一个具体工厂(例如, WindowsFactoryMacOSFactory)

为每种类型的组件公开一组一致的接口(例如,, ButtonCheckbox)

让客户端使用这些接口,而无需担心特定于平台的实现

类图

 

  1. 1. 抽象工厂 (GUIFactory)
    定义用于 创建相关产品系列的通用接口。

通常包括工厂方法,如 、 、 等。createButton()createCheckbox()createTextField()

客户端依靠此接口创建对象,而无需知道其具体类型。

  1. 2. 混凝土厂 (, WindowsFactoryMacOSFactory)
    实现抽象工厂接口。

创建 属于特定系列或平台的具体产品变型。

每个工厂都确保其生产的所有组件都是兼容的(即属于同一平台/主题)。

  1. 3. 抽象产品 (, ButtonCheckbox)
    为 一组相关组件定义接口或抽象类。

给定类型(例如,,)的所有产品变体都 将实现这些接口。WindowsButtonMacOSButton

  1. 4. 混凝土产品 (, WindowsButtonMacOSCheckbox)
    实现抽象产品接口。

包含 组件的特定于平台的逻辑和外观。

  1. 5. 客户 (Application)
    使用抽象工厂和抽象产品接口。

完全不知道它正在使用的具体类——它只与工厂和产品接互。

可以通过更改出厂方式切换整个产品系列(例如,从 Windows 切换到 macOS),而无需接触 UI 逻辑。

实现抽象工厂
让我们实现一个系统,让我们的应用程序可以为 Windows 和 macOS 生成具有本机外观的 UI 组件(按钮、复选框), 而无需硬编码平台检查或复制逻辑。

  1. 1. 定义抽象产品接口
    我们首先定义客户端使用的产品接口。

Button

public interface Button {void paint();void onClick();
}

Checkbox

public interface Checkbox {void paint();void onSelect();
}
  1. 2. 创建具体产品类
    这些实现特定于平台的逻辑。

Windows 组件

public class WindowsButton implements Button {@Overridepublic void paint() {System.out.println("Painting a Windows-style button.");}@Overridepublic void onClick() {System.out.println("Windows button clicked.");}
}public class WindowsCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Painting a Windows-style checkbox.");}@Overridepublic void onSelect() {System.out.println("Windows checkbox selected.");}
}

macOS 组件

public class WindowsCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Painting a Windows-style checkbox.");}@Overridepublic void onSelect() {System.out.println("Windows checkbox selected.");}
}public class MacOSCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Painting a macOS-style checkbox.");}@Overridepublic void onSelect() {System.out.println("MacOS checkbox selected.");}
}
  1. 3. 定义抽象工厂
    这是用于创建相关产品系列的界面。
public interface GUIFactory {Button createButton();Checkbox createCheckbox();
}
  1. 4. 实施混凝土工厂
    每个工厂都会创建特定于平台的组件变体。

WindowsFactory

public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic Checkbox createCheckbox() {return new WindowsCheckbox();}
}

MacOSFactory

public class MacOSFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacOSButton();}@Overridepublic Checkbox createCheckbox() {return new MacOSCheckbox();}
}
  1. 5. 客户端代码 – 仅使用抽象接口
    客户端代码根据作系统选择工厂,并使用它来创建 UI 组件。
public class Application {private final Button button;private final Checkbox checkbox;public Application(GUIFactory factory) {this.button = factory.createButton();this.checkbox = factory.createCheckbox();}public void renderUI() {button.paint();checkbox.paint();}
}
  1. 6. 申请切入点

输出(在 macOS 上)

Painting a macOS-style button.
Painting a macOS-style checkbox.

输出(在 Windows 上)

Painting a Windows-style button.
Painting a Windows-style checkbox.

我们取得了什么成就
平台独立性:应用程序代码从不引用特定于平台的类
一致性:按钮和复选框始终与所选作系统样式匹配
开放/封闭原则:在不修改现有工厂或组件的情况下添加对 Linux 或 Android 的支持
可测试性和灵活性:工厂可以轻松更换以进行测试或主题
其他资料:

https://pan.baidu.com/s/1c1oQItiA7nZxz8Rnl3STpw?pwd=yftc
https://pan.quark.cn/s/dec9e4868381

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

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

相关文章

WSL 下的虚拟网卡配置

第一部分:Windows 虚拟网卡创建指南 1. 原理 在 Windows 里,“虚拟网卡”本质是由网络驱动在系统网络栈中创建的一个 软件网卡接口。它的作用和物理网卡类似,只不过不直接连接到物理硬件,而是通过内核网络驱动与宿主机网络进行交换…

Dify web前端源码本地部署详细教程

目录 1. 先启动API 2. 启动worker服务 3. 启动web 4. 访问登陆地址 在前面的文章中,Dify源码部署,搭建二次开发环境(一) 已经记录了如何在本地启动API、work、中间件。在本篇文章中,将概述如何启动dify web源码项…

CVPR 2025|英伟达联合牛津大学提出面向3D医学成像的统一分割基础模型

在 2D 自然图像和视频的交互式分割领域,基础模型已引发广泛关注,这也促使人们开始构建用于医学成像的 3D 基础模型。然而,3D 医学成像存在的领域差异以及临床应用场景,要求开发一种有别于现有 2D 解决方案的专用模型。具体而言&am…

解决“Win7共享文件夹其他电脑网络无法发现共享电脑名称”的问题

要让运行 Windows 7 的电脑被局域网中其他设备(包括另一台电脑、手机、NAS 等)“发现”,必须同时满足三个条件: 网络发现功能已启用;对应的后台服务已启动;防火墙规则放行。 下面给出最简、最稳妥的 3 步设…

Python pyzmq 库详解:从入门到高性能分布式通信

一、前言 在现代软件开发中,进程间通信(IPC)与分布式系统通信已经成为基础能力。无论是构建一个微服务架构的后端,还是实现大规模并行计算任务,如何让不同的进程或节点之间高效地传递消息,都是核心问题。 传…

CentOS 7更换国内镜像源

第一步:检查系统版本 在修改任何配置之前,先确定你的 CentOS 版本,因为不同版本的镜像源配置文件不同。 cat /etc/redhat-release这个命令会显示你的 CentOS 版本信息,例如 CentOS Linux release 7.9.2009 (Core)。从你的错误日志…

详解 doclayout_yolo:Python 文档布局检测

目录一、doclayout_yolo 核心功能二、安装方法1. 直接安装2. 通过 PDF-Extract-Kit 安装三、使用示例1. 快速体验(HuggingFace Demo)2. 本地推理代码3. 批量处理四、技术亮点五、应用场景六、其他说明1.相关资源2. 注意事项doclayout_yolo 是一个基于 Y…

猫头虎AI分享|一款Coze、Dify类开源AI应用超级智能体Agent快速构建工具:FastbuildAI

猫头虎AI分享|一款 Coze、Dify 类开源 AI 应用超级智能体快速构建工具:FastbuildAI 区别在于它的易用度和商业闭环功能 摘要:FastbuildAI 是一个开源的 AI 应用“快速构建 商业化闭环”工具。它让个人开发者与小团队用 可视化 零代码 的方…

GitLab 安全漏洞 CVE-2025-6186 解决方案

本分分享极狐GitLab 补丁版本 18.2.2, 18.1.4, 18.0.6 的详细内容。这几个版本包含重要的缺陷和安全修复代码,我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS,技术团队已经进行了升级,无需用户采取任何…

【K8s】harbor安装与推送镜像

引言 在开发中,先推送镜像到docker,然后直接在docker运行。但是在K8S中,需要动态创建或者分配机器,这里需要将镜像推送到harbor仓库,然后再从仓库拉取到每台集群机器。 docker安装harbor:https://learnku…

FPGA读取AHT20温湿度模块思路及实现,包含遇到的问题(IIC协议)

一.阅读官方手册 手册在下方网址下载,该模块在各个网店平台均有销售 百度网盘 请输入提取码 手册重点关注IIC地址(读地址0x71,写地址0x70)、IIC命令和读写数据逻辑,手册写的比较简单(感觉很多细节没到位…

项目会议怎么开才有效

要提高项目会议的有效性,需要做到以下几点:明确会议目的、制定具体的会议议程、合理控制会议时长、提前准备会议资料、选择合适的参会人员、设定清晰的会议目标、确保会议有决策和行动方案、会后及时跟进与落实。其中,明确会议目的尤为重要。…

计算机视觉第一课opencv(二)保姆级教

目录 简介 一、边界填充 1.函数说明 2.案例分析 二、图像运算 1.号运算 2.cv2.add()函数 3.图像加权运算 三、阈值处理 四、图像平滑处理 1.椒盐噪声 2.均值滤波(Mean Filtering) 3.方框滤波 4. 高斯滤波(Gaussian Filtering&am…

母猪姿态转换行为识别:计算机视觉与行为识别模型调优指南

> 在现代智能化养殖中,母猪姿态识别是健康监测的关键技术。本文将带你从0到1构建高精度母猪姿态识别系统,准确率可达95%以上! ## 一、为什么母猪姿态识别如此重要? 母猪的行为姿态是其健康状况的重要指标: - **站立姿态**:可能表示发情期或进食需求 - **侧卧姿态**:…

循序渐进学 Spring (下):从注解、AOP到底层原理与整合实战

文章目录7. 自动装配 (Autowiring)7.1 XML 自动装配7.2 使用注解实现自动装配Autowired vs Resource8. 使用注解开发(完全体)8.1 定义 Bean (Component 及其衍生注解)8.2 注入属性 (Value)8.3 注入对象8.4 定义作用域 (Scope)8.5 小结:XML vs…

C#WPF实战出真汁06--【系统设置】--餐桌类型设置

1、系统设置的基本概念系统设置是用于配置和管理餐桌类型和菜品类型,是维护整个系统的基础数据。通过系统设置,用户可以调整餐桌类型的添加,删除,编辑,分页,查询,重置,列表&#xff…

旋钮键盘项目---foc讲解(闭环位置控制)

hello,周六休息了一天,出去打本了。趁着夜色,花费了几个小时,也是将闭环代码写完,参考了灯哥的思路。接下来介绍一下我的整个流程: 一、闭环位置控制思路: 其实懂得了开环,那么闭环…

为什么有些相机“即插即用”,而有些则需要采集卡?

在工业生产中,工业相机是“眼睛”,它帮助我们看到世界,但你知道吗?不同的工业相机接口就像不同的“通道”,有些“通道”直接就能与计算机连接,而有些则需要一个额外的小配件——图像采集卡。那么&#xff0…

【计算机网络 | 第7篇】物理层基本概念

文章目录物理层基本概念及数据通信系统解析一、物理层的核心定位🥝二、物理层的功能🧾三、数据通信系统的模型🐦‍🔥(一)源系统(二)传输系统(三)目的系统四、…

一般情况下,python函数都会返回对象,但有时只调用一个函数,这是在修改这个信息

class Model:def __init__(self):self.training Truedef eval(self):self.training Falsereturn Nonem Model() print(m.training) # True m.eval() # 返回 None print(m.training) # False,模型内部状态已改变m.eval()是在修改m的…