chatGPT带你学习设计模式 (二)抽象工厂模式(创建型模式) GURU

深入理解抽象工厂模式

在这里插入图片描述

引言

在面向对象编程中,对象的创建是一个常见且关键的挑战。尤其在需要管理一系列相关对象的创建时,传统的对象创建方法(如直接使用 new 关键字)可能导致代码的高耦合和低灵活性。这时,抽象工厂模式作为一种创建型设计模式,提供了一种解决方案。

什么是抽象工厂模式?

抽象工厂模式是一种设计模式,用于处理一系列相关或相互依赖对象的创建,而无需指定它们具体的类别。这种模式通过定义一个接口来创建一组相关或依赖对象,同时确保这些创建的对象能够在逻辑上彼此搭配使用。

抽象工厂

抽象工厂提供了一个创建一系列相关或依赖对象的接口,但不指定具体类。这些对象通常属于同一个产品族。

具体工厂

具体工厂实现了抽象工厂的创建方法,负责创建一个特定产品族的所有产品。

产品族和产品等级结构

  • 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的一系列产品。
  • 产品等级结构:产品等级结构是指由不同工厂生产的相同种类的产品。

示例:C#中的抽象工厂模式

场景描述

假设我们正在开发一个UI库,它能够在不同的操作系统上生成不同风格的UI元素。我们的目标是创建一个工厂,它可以生成按钮和复选框,这些UI元素在不同操作系统(如Windows和macOS)下有不同的实现。

步骤1:定义抽象产品

首先,我们定义UI元素的抽象接口。在我们的例子中,这将是Button和Checkbox。

public interface IButton
{void Paint();
}public interface ICheckbox
{void Render();
}

步骤2:创建具体产品

接着,为每个操作系统创建具体的产品类。

public class WindowsButton : IButton
{public void Paint(){Console.WriteLine("Rendering a button in a Windows style.");}
}public class MacOSButton : IButton
{public void Paint(){Console.WriteLine("Rendering a button in a macOS style.");}
}public class WindowsCheckbox : ICheckbox
{public void Render(){Console.WriteLine("Rendering a checkbox in a Windows style.");}
}public class MacOSCheckbox : ICheckbox
{public void Render(){Console.WriteLine("Rendering a checkbox in a macOS style.");}
}

步骤3:定义抽象工厂

定义一个抽象工厂接口,它包含创建所有种类产品的方法。

public interface IGUIFactory
{IButton CreateButton();ICheckbox CreateCheckbox();
}

步骤4:实现具体工厂

为每个操作系统实现一个具体的工厂。

public class WindowsFactory : IGUIFactory
{public IButton CreateButton(){return new WindowsButton();}public ICheckbox CreateCheckbox(){return new WindowsCheckbox();}
}public class MacOSFactory : IGUIFactory
{public IButton CreateButton(){return new MacOSButton();}public ICheckbox CreateCheckbox(){return new MacOSCheckbox();}
}

步骤5:使用工厂 客户端使用

客户端代码现在可以使用抽象工厂和抽象产品接口,无需关心具体的实现。

public class Application
{private IButton _button;private ICheckbox _checkbox;private IGUIFactory _factory;public Application(IGUIFactory factory){_factory = factory;}public void CreateUI(){_button = _factory.CreateButton();_checkbox = _factory.CreateCheckbox();}public void Paint(){_button.Paint();_checkbox.Render();}
}public class Program
{public static void Main(string[] args){IGUIFactory factory;if (OperatingSystem.IsWindows()){factory = new WindowsFactory();}else{factory = new MacOSFactory();}Application app = new Application(factory);app.CreateUI();app.Paint();}
}

优点

  • 保证产品一致性:确保同一工厂生产的产品在逻辑上是一致的。
  • 减少耦合度:客户端代码与具体产品类解耦,易于扩展和维护。
  • 支持扩展:添加新产品族时,无需修改现有代码。

局限性

  • 难以支持新种类产品:扩展工厂以生产新种类产品时可能需要修改接口,这可能会违反开闭原则。

结论

抽象工厂模式是管理和创建相关对象系列的一个强大工具。它不仅提高了代码的模块化和可扩展性,而且减少了客户端代码与应用程序的具体实现之间的耦合。这种模式特别适用于那些需要处理一系列相互关联或依赖对象的场景,尤其是在这些对象需要跨平台或具有不同表示时。

实际应用

在实际开发中,抽象工厂模式广泛应用于UI框架、跨平台应用和数据库访问等场景。例如,在UI框架中,根据不同的操作系统(如Windows、macOS、Linux)创建不同风格的UI元素,这就是一个典型的抽象工厂模式的应用场景。

设计考量

当使用抽象工厂模式时,重要的是要保持接口的一致性和简洁性。每增加一个产品或产品族,都可能需要重新考虑工厂接口的设计。因此,在设计时应考虑到可能的扩展性和变化,以避免未来的重构成本。

与工厂方法模式的比较

抽象工厂模式经常与工厂方法模式相混淆。两者的主要区别在于:

  • 工厂方法模式:用于创建一个产品,由子类决定实例化哪一个类。工厂方法模式使用继承和子类来决定应该实例化哪一个类。
  • 抽象工厂模式:用于创建一系列相关或依赖对象,而不仅仅是一个对象。这些对象通常属于同一个产品族。

最佳实践

当系统需要处理不同系列的相关产品,并且系统中的一组对象需要一起使用时,应该考虑使用抽象工厂模式。
当需要提供一个产品类库,并只想显示它们的接口而不是实现时,可以使用抽象工厂。

结语

抽象工厂模式是一种高级的设计模式,它能够提供一个强大的方式来封装一系列创建对象的逻辑。通过实现这种模式,可以帮助我们构建更加灵活、可扩展和可维护的代码,特别是在处理一系列相关对象时。正如我们在C#示例中看到的那样,抽象工厂模式可以清晰地将产品的创建逻辑与其使用逻辑分离,从而提高整个系统的设计质量。

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

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

相关文章

JSUDO|加速度与阿里云合作云产品

电讯:深圳市加速度软件开发有限公司【加速度jsudo】,与阿里云计算有限公司(简称“阿里云”)达成合作,双方将在电商、企业管理等应用软件领域就云产品和应用软件更深层次合作。 加速度软件长期以来,一直与阿…

jquery图形验证码

效果展示 js图形随机验证码&#xff08;表单验证&#xff09; html代码片段 <form class"formwrap"><div class"item"><input type"text" id"code_input" value"" placeholder"请输入验证码"/>…

网络调试 UDP1,开发板用动态地址-入门6

https://www.bilibili.com/video/BV1zx411d7eC?p11&vd_source109fb20ee1f39e5212cd7a443a0286c5 1, 开发板连接路由器 1.1&#xff0c;烧录无OS UDP例程 1.2&#xff0c;Mini USB连接电脑 1.3&#xff0c;开发板LAN接口连接路由器 2. Ping开发板与电脑之间通信* 2.1 根据…

探索PyTorch优化和剪枝技术相关的api函数

torch.nn子模块Utilities解析 clip_grad_norm_ torch.nn.utils.clip_grad_norm_ 是 PyTorch 深度学习框架中的一个函数&#xff0c;它主要用于控制神经网络训练过程中的梯度爆炸问题。这个函数通过裁剪梯度的范数来防止梯度过大&#xff0c;有助于稳定训练过程。 用途 防止…

java实验室预约管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java servlet 实验室预约管理系统是一套完善的java web信息管理系统 系统采用serlvetdaobean&#xff08;mvc模式)&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数 据库&#xff0c;系统主要采用B/S模式开发。开发环境为T…

性能优化-OpenMP基础教程(四)-Android上运行OpenMP

本文主要介绍如何在一个常规的Android手机上调试OpenMP程序&#xff0c;包括Android NDK的环境配置和使用JNI编写一个OpenMP程序运行在Android手机中。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#…

ElasticSearch使用Grafana监控服务状态-Docker版

文章目录 版本信息构建docker-compose.yml参数说明 创建Prometheus配置文件启动验证配置Grafana导入监控模板模板说明 参考资料 版本信息 ElasticSearch&#xff1a;7.14.2 elasticsearch_exporter&#xff1a;1.7.0&#xff08;latest&#xff09; 下载地址&#xff1a;http…

WSL使用Ubuntu 20.04版本运行py-bottom-up-attention的记录,及其可能错误的解决方法

文章目录 1. 切换linux的镜像2. 安装gcc3. 查看显卡驱动4. 安装gcc版本5. wsl安装cuda 10.16. 新建虚拟环境8. 安装依赖包9. 运行代码错误运行的所有历史命令如下 WSL使用Ubuntu 20.04版本运行py-bottom-up-attention的记录&#xff0c;及其可能错误的解决方法 github代码地址…

线性渐变linear-gradient——线性渐变实现虚线斜线条纹

1.效果图 2.html <div class"box"><div class"address-edit"></div></div> 3.css <style>*{margin: 0;padding: 0;}.box{position: relative;width: 100vw;height: 300px;background-color: #fff;}.address-edit::before…

JetPack组件学习ViewModel

ViewModel的使用 1.需要先创建ViewModel类&#xff0c;继承自ViewModel重写onclear方法&#xff0c;使得页面销毁的时候能够走到自定义的onClear方法中 class MyViewModel : ViewModel() {//共享数据的核心在于拿到同一个LiveData实例&#xff0c;也就是拿到同一个ViewModel实…

如何成为ChatGPT 优质Prompt创作者

如何提问&#xff1f; 我想让你成为我的Prompt创作者。你的目标是帮助我创作最佳的Prompt&#xff0c;这个Prompt将由你ChatGPT使用。你将遵循 以下过程&#xff1a;1.首先&#xff0c;你会问我Prompt是关于什么&#xff1f;我会告诉你&#xff0c;但我们需要 通过不断的重复来…

Redis高并发高可用(主从复制、哨兵)

复制 在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡等需求。Redis也是如此,它为我们提供了复制功能,实现了相同数据的多个Redis 副本。复制功能是高可用Redis的基础,哨兵和集群都是在复制的基础上实现高可用的。 默认…

YOLOv8 Ultralytics:使用Ultralytics框架进行姿势估计

YOLOv8 Ultralytics&#xff1a;使用Ultralytics框架进行姿势估计 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows 使用Ultralytics框架进行姿势估计参考文献 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&#xff0c;可…

新手练习项目 4:简易2048游戏的实现(C++)

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#xff09; 目录 一、效果图二、代码&#xff08;带注释&#xff09;三、说明 一、效果图 二、代码&#xff08;带…

微软 Power Platform 使用Power Automate发送邮件以Dataverse作为数据源的附件File Column

微软Power Platform使用Power Automate发送邮件添加Power Apps以Dataverse作为数据源的附件File Column方式 目录 微软Power Platform使用Power Automate发送邮件添加Power Apps以Dataverse作为数据源的附件File Column方式1、需求背景介绍2、附件列File Column介绍3、如何在Po…

jenkins忘记密码后的操作

1、先停止 jenkins 服务 systemctl stop jenkins 关闭Jenkins服务 或者杀掉进程 ps -ef | grep jenkins &#xff5c;awk {print $2} | grep -v "grep" | xargs kill -9 2、找到 config.xml 文件 find /root -name config.xml3、备份config.xml文件 cp /root/.jen…

猫头虎分享已解决Bug || TypeError: Cannot read property ‘match‘ of undefined

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

HPM6750开发笔记《DMA接收和发送数据UART例程深度解析》

目录 概述&#xff1a; 端口设置&#xff1a; 代码分析&#xff1a; 运行现象&#xff1a; 概述&#xff1a; DMA&#xff08;Direct Memory Access&#xff09;是一种计算机系统中的数据传输技术&#xff0c;它允许数据在不经过中央处理器&#xff08;CPU&#xff09;的直…

MYSQL篇--索引高频面试题

mysql索引 1什么是索引&#xff1f; 索引说白了就是一种数据结构&#xff0c;可以协助快速查询数据&#xff0c;以及更新数据库表中的数据&#xff0c;更通俗的来说索引其实就是目录&#xff0c;通过对数据建立索引形成目录&#xff0c;便于去查询数据&#xff0c;而mysql索引…

cmd命令启动C# windows服务程序

因为Process.Manage.Service.exe程序为Windows服务程序&#xff0c;不能直接双击打开&#xff0c;所以需要借助windows系统自带InstallUtil.exe程序来启动它。 以管理员身份运行cmd命令控制台窗口 输入命令进入到InstallUtil.exe程序所在的文件夹 cd C:\Windows\Microsoft.NET…