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#示例中看到的那样,抽象工厂模式可以清晰地将产品的创建逻辑与其使用逻辑分离,从而提高整个系统的设计质量。

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

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

相关文章

rime中州韵小狼毫 中英互绎 滤镜

英文在日常生活中已经随处可见,我们一般中英互译需要使用专业的翻译软件来实现。但如果我们在输入法中,在输入中文的时候,可以顺便瞟一眼对应的英文词汇,或者在输入英文的时候可以顺便了解对应的中文词汇,那将为我们的…

【Qt第三方库】QXlsx库——对 Excel 文件进行相关操作

0 前言 关键词:Qt;Excel;QXlsx;QInt 简介: QXlsx 是第三方开源的库,能够对 Excel 文件进行相关操作(读写等) 地址: QXlsx官网 QXlsx的Github主页 1 快速上手 对于第一次…

设置代理IP地址对网络有什么影响?爬虫代理IP主要有哪些作用?

在互联网的广泛应用下,代理IP地址成为了一种常见的网络技术。代理IP地址可以改变用户的上网行为,进而影响网络访问的速度和安全性。本篇文章将探讨设置代理IP地址对网络的影响,以及爬虫代理IP的主要作用。 首先,让我们来了解一下代…

【Java】实验三 抽象类与接口

实验名称 实验三 抽象类与接口 实验目的 1. 深刻理解抽象类、接口的意义。 2. 熟练掌握抽象类和接口的定义、继承抽象类以及实现接口的方法。 3. 理解和掌握多态。 实验内容 (一)抽象类实验:项目源码中新建一个ahpu.shape的包&a…

Transformer从菜鸟到新手(一)

引言 这是从Transformer到LLM(大语言模型)系列的第一篇文章,几乎所有的大语言模型都是基于Transformer结构,因此本文回顾一下Transformer的原理与实现细节,包括分词算法BPE的实现。最终利用从零实现的Transformer模型进行英中翻译。 本文主…

IOS:Safari无法播放MP4(H.264编码)

一、问题描述 MP4使用H.264编码通常具有良好的兼容性,因为H.264是一种广泛支持的视频编码标准。它可以在许多设备和平台上播放,包括电脑、移动设备和流媒体设备。 使用caniuse查询H.264兼容性,看似确实具有良好的兼容性: 然而…

Windows系统镜像检测修复建议

当通过镜像检测功能检测出Windows操作系统磁盘上有残留驱动项、系统中存在残留Xen驱动或者存在禁止安装驱动属性设置等异常检测项时,您可以参考本文的操作指导进行修复。 清理注册表残留驱动 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control注册表树包含了控…

c++基础(对c的扩展)

文章目录 命令空间引用基本本质引用作为参数引用的使用场景 内联函数引出基本概念 函数补充默认参数函数重载c中函数重载定义条件函数重载的原理 命令空间 定义 namespace是单独的作用域 两者不会相互干涉 namespace 名字 { //变量 函数 等等 }eg namespace nameA {int num;v…

TextView ClickableSpan 事件分发的坑

TextView 的 ClickableSpan 有两个坑: 默认情况下,点击 ClickableSpan 的文本时会同时触发绑定在 TextView 的监听事件;默认情况下,点击 ClickableSpan 的文本之外的文本时,TextView 会消费该事件,而不会传…

MySQL运维实战(2.2)忘记密码如何处理

作者:俊达 引言 当你突然忘记了一个普通用户的密码,而又想着通过管理员账号去改密码时,却猛的发现所有管理员账号的密码都离谱地被你忘了。嗨呀,这可真是个尴尬的大麻烦!root账户通常是MySQL中的大boss,你…

Redis(一)

1、redis Redis是一个完全开源免费的高性能(NOSQL)的key-value数据库。它遵守BSD协议,使用ANSI C语言编写,并支持网络和持久化。Redis拥有极高的性能,每秒可以进行11万次的读取操作和8.1万次的写入操作。它支持丰富的数…

【LeetCode:69. x 的平方根 | 二分】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

程序员提问的艺术:28.4K Star指南,告别成为办公室讨厌鬼!

Github: https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way 原文:http://www.catb.org/~esr/faqs/smart-questions.html ✅为什么讨厌某些提问者 未自行尝试解决问题: ❌“怎么用Java写一个排序算法?” 👍&#…

Plantuml之EBNF语法介绍(二十七)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

java spring核心技术AOP面向切面编程图文并茂包含例子demo

base Aspect-oriented programming面向切面的程序设计用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect)场景: 权限认证,日志和事务处理.demo 基本背景 // 背景: 1. 模拟数据库操作增删改查 …

tomcat session cookie值设置逻辑

tomcat session cookie 值设置,tomcat jsessionid设置 ##调用request.getSession() Controller RequestMapping("/cookie") public class CookieController {RequestMapping("/tomcatRequest")ResponseBodypublic String tomcatRequest(HttpS…

CentOS 7 实战指南:文本处理命令详解

前言 在Linux系统中,文本处理是非常基础却又必不可少的一项技能。如果你正在使用CentOS系统,那么学会如何利用文本操作命令来高效地处理文本文件无疑将会是一个强有力的工具。 本篇文章将介绍一些最常用和最实用的文本操作命令,并通过详尽的…

医院配电能效监管方案

摘要:本文以医院能源监管系统为研究对象,采用智能化技术组建数据库、构建智能化的能耗信息管理系统,实现对医院的能源利用状况进行实时、准确的动态监管。具体而言,该系统建设的主要功能是对医院的能源消耗进行采集、上报、汇总与分析,并生成动态的数据和报表曲线,以及利用分析…

访问学者J1签证的申请流程

访问学者J1签证是许多人前往美国进行学术研究和文化交流的重要途径之一。申请J1签证需要经过一系列步骤和程序,让知识人网小编带大家来了解一下申请流程吧。 首先,申请者需要确认自己符合J1签证的资格要求。这包括被美国的赞助机构或组织接受&#xff0c…

uniapp中uview组件库的Input 输入框 的使用方法

目录 #平台差异说明 #基本使用 #输入框的类型 #可清空字符 #下划线 #前后图标 #前后插槽 API #Props #Events #Methods #Slots 去除fixed、showWordLimit、showConfirmBar、disableDefaultPadding、autosize字段 此组件为一个输入框,默认没有边框和样式…