【设计模式】创建型模式——抽象工厂模式

news/2024/9/19 0:57:24/ 标签: 设计模式, 抽象工厂模式

抽象工厂模式

  • 1. 模式定义
  • 2. 模式结构
  • 3. 实现
    • 3.1 实现抽象产品接口
    • 3.2 定义具体产品
    • 3.3 定义抽象工厂接口
    • 3.4 定义具体工厂
    • 3.5 客户端代码
  • 4. 模式分析
    • 4.1 抽象工厂模式退化为工厂方法模式
    • 4.2 工厂方法模式退化为简单工厂模式
  • 5. 模式特点
    • 5.1 优点
    • 5.2 缺点
  • 6. 适用场景
    • 6.1 需要创建一组相关或相互依赖的对象
    • 6.2 系统不应依赖于产品类的具体实现
    • 6.3 需要提供一组产品的多种变体
  • 7. 模式扩展
    • 7.1 “开闭原则”的倾斜性
      • 7.1.1 增加产品族:
      • 7.1.2 增加产品等级结构:


1. 模式定义

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

2. 模式结构

抽象工厂模式包含如下角色:

  • AbstractFactory:抽象工厂
  • ConcreteFactory:具体工厂
  • AbstractProduct:抽象产品
  • Product:具体产品
    在这里插入图片描述

3. 实现

3.1 实现抽象产品接口

首先,定义两个抽象产品接口:Button 和 TextBox。

package mainimport "fmt"// Button 是按钮的抽象接口
type Button interface {Render()
}// TextBox 是文本框的抽象接口
type TextBox interface {Render()
}

3.2 定义具体产品

这些类实现了抽象产品接口。

// WindowsButton 是 Windows 风格的按钮
type WindowsButton struct{}func (b *WindowsButton) Render() {fmt.Println("Rendering Windows Button")
}// MacButton 是 Mac 风格的按钮
type MacButton struct{}func (b *MacButton) Render() {fmt.Println("Rendering Mac Button")
}// WindowsTextBox 是 Windows 风格的文本框
type WindowsTextBox struct{}func (t *WindowsTextBox) Render() {fmt.Println("Rendering Windows TextBox")
}// MacTextBox 是 Mac 风格的文本框
type MacTextBox struct{}func (t *MacTextBox) Render() {fmt.Println("Rendering Mac TextBox")
}

3.3 定义抽象工厂接口

声明了创建一组相关对象的方法。

// GUIFactory 是 GUI 工具包的抽象工厂接口
type GUIFactory interface {CreateButton() ButtonCreateTextBox() TextBox
}

3.4 定义具体工厂

这些类实现了抽象工厂接口。

// WindowsFactory 是 Windows 风格的 GUI 工具包工厂
type WindowsFactory struct{}func (f *WindowsFactory) CreateButton() Button {return &WindowsButton{}
}func (f *WindowsFactory) CreateTextBox() TextBox {return &WindowsTextBox{}
}// MacFactory 是 Mac 风格的 GUI 工具包工厂
type MacFactory struct{}func (f *MacFactory) CreateButton() Button {return &MacButton{}
}func (f *MacFactory) CreateTextBox() TextBox {return &MacTextBox{}
}

3.5 客户端代码

使用抽象工厂模式创建一组相关对象。

func main() {var factory GUIFactory// 可以根据需要选择不同的工厂factory = &WindowsFactory{}// factory = &MacFactory{}button := factory.CreateButton() //Rendering Windows ButtontextBox := factory.CreateTextBox() //Rendering Windows TextBoxbutton.Render() //Rendering Mac ButtontextBox.Render() //Rendering Mac TextBox
}

4. 模式分析

4.1 抽象工厂模式退化为工厂方法模式

  • 条件: 每个具体工厂类只创建一个产品对象,即只存在一个产品等级结构。
  • 结果: 抽象工厂模式退化为工厂方法模式,因为不再需要创建多个相关的产品对象。

4.2 工厂方法模式退化为简单工厂模式

  • 条件: 抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的方法设计为静态方法。
  • 结果: 工厂方法模式退化为简单工厂模式,因为所有产品对象的创建都由一个统一的工厂类负责。

5. 模式特点

5.1 优点

  • 确保同一产品族的对象一起工作。
  • 客户端不需要知道每个对象的具体类,简化了代码。

5.2 缺点

扩展产品族非常困难。增加一个新的产品族需要修改抽象工厂和所有具体工厂的代码。

6. 适用场景

6.1 需要创建一组相关或相互依赖的对象

当系统需要创建一组相关或相互依赖的对象时,抽象工厂模式可以确保这些对象的一致性和兼容性。例如,创建不同风格的 GUI 组件(按钮、文本框等)。

6.2 系统不应依赖于产品类的具体实现

当系统不应依赖于产品类的具体实现,而是通过接口来操作对象时,抽象工厂模式可以提供一个统一的接口来创建对象。

6.3 需要提供一组产品的多种变体

当系统需要提供一组产品的多种变体(如不同平台的 GUI 组件),并且客户端代码需要透明地使用这些变体时,抽象工厂模式是一个合适的选择。

7. 模式扩展

7.1 “开闭原则”的倾斜性

7.1.1 增加产品族:

  • 支持良好: 当需要增加新的产品族(例如,不同风格的按钮和文本框)时,只需添加新的具体工厂类和相应的产品类,而无需修改现有的代码。这符合开闭原则,因为系统对扩展开放,对修改封闭。

7.1.2 增加产品等级结构:

  • 支持不佳: 当需要增加新的产品等级结构(例如,新增一种产品类型如复选框)时,必须修改抽象工厂接口和所有具体工厂类,添加创建新产品的方法。这违反了开闭原则,因为需要修改现有的代码。

http://www.ppmy.cn/news/1519333.html

相关文章

3.6 Browser -- useFullscreen

3.6 Browser – useFullscreen https://vueuse.org/useFullscreen 作用 响应式的Fullscreen API。可以让特定的元素占满屏幕&#xff0c;就是全屏的效果。 官方示例 const el ref<HTMLElement | null>(null)const { isFullscreen, enter, exit, toggle } useFulls…

【SpringMVC】

深入探索SpringMVC&#xff1a;构建高效、可维护的Web应用1. SpringMVC 核心概念1.1 模型&#xff08;Model&#xff09;1.2 视图&#xff08;View&#xff09;1.3 控制器&#xff08;Controller&#xff09; 2. SpringMVC 入门2.1 环境搭建2.2 配置前端控制器2.3 开发第一个Co…

25版王道数据结构课后习题详细分析 第五章 树与二叉树 5.3 二叉树的遍历和线索二叉树 选择题部分

一、单项选择题 ———————————————————— ———————————————————— 解析&#xff1a;二叉树中序遍历的最后一个结点一定是从根开始沿右子女指针链走到底的结点,设用p指示。若结点p不是叶结点(其左子树非空)&#xff0c;则前序遍历的最后一…

Windows10上Nginx如何通过自签名证书方式发布Https服务(下)

4.客户端证书生成 4.1 生成私钥 命令: openssl genrsa -des3 -out client.key 1024 4.2 创建 CSR(证书签名请求) 配置文件:client_openssl.cnf [req] distinguished_name = req_distinguished_name req_extensions = v3_req[req_distinguished_name] countryName …

nrm|npm快速切源

npm ERR! audit Your configured registry (https://registry.npmmirror.com/) does not support audit requests. 直接切源就 ok 了 全局安装 $npm i -g nrm查看所有源 $ nrm ls* npm -------- https://registry.npmjs.org/yarn ------- https://registry.yarnpkg.com/cnpm …

图像处理 -- 图像清晰度测量方法

图像清晰度测量方法 拉普拉斯算子&#xff08;Laplacian Operator&#xff09; 拉普拉斯算子是一种二阶导数算子&#xff0c;用于检测图像的边缘。清晰的图像通常具有更多且更明显的边缘。 边缘检测&#xff08;Edge Detection&#xff09; 常用的边缘检测算法包括Sobel、Prew…

深度学习100问39:阿达玛乘积在实际生活中的应用

嘿&#xff0c;你知道吗&#xff1f;阿达玛乘积在我们的生活中可有着不少神奇的应用呢&#xff01; 一、图像处理领域 在图像处理的世界里&#xff0c;阿达玛乘积就像是一个神奇的画笔。比如说图像融合吧&#xff0c;想象一下&#xff0c;你有两张超酷的照片&#xff0c;一…

成功解决:jenkins构建失败,cannot open directory /home/centos/: Permission denied等问题

这是报错: LANG=en_US.UTF-8 JOB_NAME=interface_automation_testing BUILD_DISPLAY_NAME=#25 BUILD_ID=25 NOTIFY_SOCKET=/run/systemd/notify JOB_BASE_NAME=interface_automation_testing GIT_PREVIOUS_SUCCESSFUL_COMMIT

EventBus使用详解

EventBus是一个由GreenRobot开发的开源库&#xff0c;主要用于Android和Java编程中的事件发布/订阅框架。它基于观察者模式&#xff0c;将事件的接收者和发送者分开&#xff0c;简化了组件之间的通信&#xff0c;使用简单、效率高、体积小。以下是对EventBus使用的详细解析&…

13 隔离性

数据库并发的场景 读-读&#xff1a;不存在任何问题&#xff0c;也不需要并发控制 读-写&#xff1a;有线程安全问题&#xff0c;可能会造成事务隔离性问题&#xff0c;可能遇到脏读&#xff0c;幻读&#xff0c;不可重复读 写-写&#xff1a;有线程安全问题&#xff0c;可能存…

VIVO 相机HDR拍照流程拆解

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: HDR 场景下发 3 帧拍照请求HDR 3帧拍照请求帧&#xff08;478,479 480&#xff09;HDR 3帧 result callback帧HDR 算法处理5.算法编解码处理HDR 拍照lo…

SpringMVC接收返回值方法汇总

传统方式 RequestMapping("/param01") public String param01(HttpServletRequest request) throws UnsupportedEncodingException {request.setCharacterEncoding("UTF-8");String id request.getParameter("id");request.setAttribute("…

Linux基础入门 --2 DAY

常见命令 查看硬件信息 查看cpu lscpu cat /proc/cpuinfo 范例&#xff1a; [rootlocalhost ~]# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 Thr…

Scipy||第三章 线性代数 (scipy.linalg)

3.1 矩阵操作的细节 3.1.1 矩阵的创建与基础运算 矩阵在 Scipy 中通常是以 Numpy 的 ndarray 形式表示的&#xff0c;这样便于进行高效的矩阵运算。我们再详细探讨几种常见的矩阵操作。 矩阵相加&#xff1a;矩阵相加要求两个矩阵的形状相同&#xff0c;元素逐个相加。 C A …

离线二维数点

问题&#xff1a;给你一个长度为n的序列&#xff0c;m次询问&#xff0c;每次询问区间[l,r]中小于等于x的元素个数。 对于此种问题&#xff0c;最简单的解法就是扫描线树状数组。这种问题满足离线性质&#xff0c;可以先把询问存下来&#xff0c;我们对原序列扫描&#xff0c;…

安达发|户外设备制造APS排程的多层级BOM订单拉动

户外设备制造行业面临的挑战包括多样化的产品线、复杂的产品开发过程以及市场需求的快速变化。为提高生产效率与市场响应速度&#xff0c;采用高级计划排程的多层级BOM订单拉动策略至关重要。 一、户外设备制造行业概述 - 行业背景&#xff1a;户外设备制造行业主要涉及户外休…

Mac 安装Hadoop教程

1. 引言 本教程旨在介绍在Mac 电脑上安装Hadoop&#xff0c;便于编程开发人员对大数据技术的熟悉和掌握。 2.前提条件 2.1 安装JDK 想要在你的Mac电脑上安装Hadoop&#xff0c;你必须首先安装JDK。具体安装步骤这里就不详细描述了。你可参考Mac 安装JDK8。 2.2 配置ssh环境…

缓存Mybatis一级缓存与二级缓存

缓存 为什么使用缓存 缓存(cache)的作用是为了减去数据库的压力,提高查询性能,缓存实现原理是从数据库中查询出来的对象在使用完后不销毁,而是存储在内存(缓存)中,当再次需要获取对象时,直接从内存(缓存)中提取,不再向数据库执行select语句,从而减少了对数据库的查询次数,因此…

Mac/Linux系统matplotlib中文支持问题

背景 matplotlib是python中最常用的数据可视化分析工具&#xff0c;Mac和Linux系统无中文字体&#xff0c;不支持中文显示&#xff08;希望后续可以改进&#xff09;&#xff0c;需要进行字体的下载和设置才能解决。笔者经过实践&#xff0c;发现Mac系统和Linux系统解决方案略…

Windows系统Nginx下载安装配置 运行错误处理

Nginx是一款轻量级的web 服务器/反向代理 服务器。本篇文章主要是nginx的下载安装&#xff0c;处理运行中遇到的问题&#xff0c;配置反向代理。主要分为两部分&#xff1a;下载安装和配置。 目录 1.下载安装 2.nginx配置反向代理 1.下载安装 nginx官网&#xff1a;nginx: …