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.mzph.cn/news/603510.shtml

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

相关文章

jmeter连接数据库

下载jdbc 在浏览器输入 mysql jdbc官网 ; 网址:MySQL :: MySQL Connectors 点击 Download 查看自己mysql服务的版本,找到对应版本的jdbc 所以下载5版本的jdbc 安装jdbc(绿色版安装) 操作jmeter 打开jmeter&#xff0…

前端框架中的状态管理(State Management)

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

GEE:随机数

作者:CSDN _养乐多_ 本文将介绍在 Google Earth Engine(GEE)上生成随机数的 API,可以指定随机数的生成范围、类型(整型、浮点型)、分布方式(均匀分布、正态分布)。 文章目录 一、随…

基于springboot的基于协同过滤算法的东北特产销售系统的设计与实现

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的基于协同过滤算法的东北…

2024年度 ROTS - 实时操作系统 Top 15

RTOS(实时操作系统)。 这里说的 RTOS 并非新星球大战电影中的机器人,而是物联网设备、航空系统、空中交通管制等背后的无声协调者,就在地球上。 RTOS,或称实时操作系统,设计它们是为了更好的管理资源&…

MySQL5.7 InnoDB 内存结构

官网地址:MySQL :: MySQL 5.7 Reference Manual :: 14.5 InnoDB In-Memory Structures 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. MySQL 5.7 参考手册 / ... / 缓冲池 14.5.1 缓冲池 缓冲池是…

20240106-换一种思维,工作也不过就是一种挣钱的方式而已了

今天在车上一个百度的同事聊抱怨说:累了,真的累了,干不动了,想跑路了,不想打工了。我们之前也会经常聊到和吐槽这种事情,但是我最近由于思维的一些改变,所以就想到把这个事情记录下来。 在大厂…

第四讲_css常用属性

css常用属性 1. css颜色表示方式1.1 颜色名1.2 rgb 和 rgba1.3 hex 和 hexa1.4 hsl 和 hsla 2. css 常用属性2.1 常用的文本属性2.2 常用的列表属性2.3 常用的边框属性2.4 表格独有属性2.5 常用的背景属性2.6 常用的鼠标属性 1. css颜色表示方式 1.1 颜色名 在css中定义了一些…

华为OD机试 - 矩阵匹配(Java JS Python C)

题目描述 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式: N M K N*M矩阵 输出描述 N*M 的矩阵中可以选出 M! / N! 种组合数…

NumPy 高级教程——并行计算

Python NumPy 高级教程:并行计算 并行计算是在多个处理单元上同时执行计算任务的方法,以提高程序的性能。在 NumPy 中,可以使用一些工具和技术来进行并行计算,充分利用多核处理器的优势。在本篇博客中,我们将深入介绍…

1871_什么是PCB

Grey 全部学习内容汇总: https://github.com/GreyZhang/g_hardware_basic 1871_什么是PCB 简单的PCB的缩写自然很容易理解,不过PCB涉及到的一些概念性的知识会比一个简单的缩写多得多。这里根据AD官方上的一个页面来整理一下这方面的基础知识点。 主…

书摘:C 嵌入式系统设计模式 06

本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述原书第 2 章的内容。 作为嵌入…

谷歌chrome浏览器升级 120.0 后书签显示变黑变粗的解决方式

在地址栏输入 chrome://flags, 然后搜索 chrome-refresh-2023-chrome-font, 从 default 改为 Disable 即可

pg的copy说明

copy 可以在表和文件之间交换数据 COPY table_name [ ( column_name [, ...] ) ]FROM { filename | PROGRAM command | STDIN }[ [ WITH ] ( option [, ...] ) ]COPY { table_name [ ( column_name [, ...] ) ] | ( query ) }TO { filename | PROGRAM command | STDOUT }[ [ WI…

雅思词汇——Word List 3(V2)

文章目录 1. leak [liːk]2. literature [ˈlɪtərətʃə( r)]3. suffer [ˈsʌfə( r)]4. impede [ɪmˈpiːd]5. spring [sprɪŋ]6. biological [ˌbaɪəˈlɒdʒɪkl]7. deduce [dɪˈdjuːs]8. doctorate [ˈdɒktərɪt]9. absolute [ˈbsəluːt]10. theoretical [θ…

SpringBoot+Elasticsearch使用resthighlevelclient对象查询条件为“且+或”

查询年龄为15或者16或者17或者18的且班级为1班的学生信息 在Spring Boot 中使用 RestHighLevelClient 进行 Elasticsearch 查询,您需要编写相应的查询逻辑。以下是一个简单的示例: 首先,确保您的项目中包含了 Elasticsearch 的依赖&#xf…

用php实现日历输出

上述日历功能的实现要点包括: 获取当前年份和月份: 使用date函数获取当前的年份和月份。 $year date("Y"); $month date("m");确定当前月份的第一天是星期几: 使用date函数和w格式参数获取当前月份的第一天是星期几。 …

一步一步写线程之四简单线程池

一、线程池 说起线程池,只要写过几年程序的,基本上各种语言开发的人都听说过。可能小白或者初级程序员觉得这玩意儿很高级,很高大上。其实也没什么。之所以让开发者觉得如此,主要还在于线程池一般在开发者的背后(框架…

python贪吃蛇

Python贪吃蛇游戏的示例代码: import pygame import time import random# 初始化游戏 pygame.init()# 定义颜色 white (255, 255, 255) black (0, 0, 0) red (255, 0, 0) green (0, 255, 0)# 定义游戏窗口大小和标题 display_width 800 display_height 600# …

Spring之 国际化:i18n

1、i18n概述 国际化也称作i18n,其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数。由于软件发行可能面向多个国家,对于不同国家的用户,软件显示不同语言的过程就是国际化。通常来讲,软件中的国…