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

news2024/11/15 10:22:19

抽象工厂模式

  • 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 main

import "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() Button
    CreateTextBox() 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 Button
    textBox := factory.CreateTextBox() //Rendering Windows TextBox

    button.Render() //Rendering Mac Button
    textBox.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.coloradmin.cn/o/2086370.html

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

相关文章

深入理解OJ编程中的输入输出:11个经典题目详解与技巧分享及stringstream,sort详解

文章目录 1.多组输入计算ab2.给定组数计算ab3.给定组数计算ab(如果为0则结束)4.计算一些列数的和(第一个数为0时结束)5.计算一些列数的和(告诉了有几组)6.计算一系列数的和(不告知几组和何时结束,每一组第一…

如何评估云服务器提供商可靠性与信誉度

在云计算时代,选择一个可靠和信誉良好的云服务器提供商对于个人用户和企业来说至关重要。以下是评估云服务器提供商可靠性与信誉度的关键指标和方法: 1. 服务水平协议(SLA): 可用性承诺: 查看云服务器提供…

服务器内存飙升分析小记

1. 写在最前面 这个繁忙的八月真的是转瞬即逝,我明明感觉似乎好像才八月刚开始,但是其实已经到了八月的尾巴。这个月本来想抽空整理一下学习 AI 模型相关的东西,奈何每天不是在查问题就是在查问题的路上,不是在修 Bug 就是在写 B…

AI Lossless Zoomer v3.1.0.0 — 超实用的AI无损图片放大工具

AI Lossless Zoomer 是一款基于腾讯开源 Real-ESRGAN 算法的 AI 图片无损放大工具,支持多线程和批量处理,具备自定义输出格式和路径等高级设置选项,并允许用户选择不同的 AI 引擎进行图片放大处理。此版本修复了一些小 bug,并增加…

Jhipster应用,cdn加速方案。

Jhipster, 采用springbootwebfluxreacttypescript技术栈。项目部署是采用k8shelm 部署在GCP上的,所以这个单体项目幕后是跑在pod上的。 项目上线后,发现单页面应用加载速度很慢,如图所示长时间处于加载状态: 仔细分析一下原因&am…

ESXi服务器无法安装Windows11:“不符合此版本的Windows所需最低系统要求“

目录 一、问题描述1.使用环境2.问题截图3.问题解析 二、解决方法Ⅰ1.按 ShiftF10 弹出命令提示符2.在弹出的Dos框中输入regedit,回车,进入注册表。3.打开HKEY_LOCAL_MACHINE\SYSTEM\Setup,并新建 LabConfig 的项,在 LabConfig 下创…

51单片机-静态数码管显示

时间&#xff1a;2024.8.29 作者&#xff1a;Whappy 目的&#xff1a;学习51单片机 代码&#xff1a; #include <REGX52.H> #include "intrins.h"unsigned char NixieTable[] {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79…

C++系列-STL容器之deque

STL容器之deque deque概括deque与vector内存管理的区别vector内存分配方式deque内存分配方式 deque与vector随机访问效率的区别deque与vector插入和删除操作的区别deque与vector适用场景 deque的构造函数deque的构造函数举例 deque的赋值操作deque容器的大小操作deque容器的插入…

瑞芯微RK3566开发板USB OTG模式介绍及命令切换,触觉智能EVB3566主板鸿蒙硬件厂商

一、USB OTG的模式 host模式&#xff08;下行&#xff09;&#xff1a;为u盘等设备供电&#xff0c;不可以进行调试&#xff0c;连接adb或者烧录等操作。 device模式&#xff08;上行&#xff09;&#xff1a;可以进行调试&#xff0c;连接adb或者烧录等操作&#xff0c;即US…

Delphi5实现主要——明细型数据库应用

文章目录 效果图主要——明细型数据库特点 数据库实现方式完整代码 效果图 主要——明细型数据库 在Delphi中&#xff0c;主要——明细型数据库是一种数据库应用程序的设计模式&#xff0c;它涉及到多个数据库表之间的关联操作&#xff0c;以实现对复杂数据结构的有效管理。这…

数据结构(邓俊辉)学习笔记】串 16——Karp-Rabin算法:串即是数

文章目录 1. 化串为数2. 凡物皆数3. 亦是数 1. 化串为数 接下来的这节&#xff0c;我们再来讨论一种十分另类的串匹配算法&#xff0c;也就是所谓的 Karp-Rabin 算法。回顾此前所介绍的几种串匹配算法&#xff0c;我们所面临的难题是一样的。也就是说在这里&#xff0c;我们每次…

ES配合高德地图JS-API实现地理位置查询

目录 实现功能点 技术选型 具体实现 Vue3整合高德地图JS API-2.0 添加商户&#xff1a;前端 添加商户&#xff1a;后端/ES 查询用户当前地理坐标 获取附近&#xff08;指定距离&#xff09;的商户 总结/测试Demo代码地址 测试概述&#xff1a;用户使用高德地图组件获取商户…

GPT实现的adb shell命令实现某音自动点赞和关注

摘要:这个可能是没啥用的自动点赞和关注功能,自娱自乐为主哈 具体可行性步骤如下: 1.打开手机的开发者选项,将指针位置的设置开关打开,目的是看触屏时的坐标值 2.随便打开一个抖音,找到点赞的爱心图标的坐标轴,并记下来,待会有用 备注:尽量获取爱心尖端的坐标值,由…

erlang学习:用OTP构建系统2,警报管理

今日学习用OTP构建系统的警报管理&#xff0c; 首先进行配置错误记录器 [{sasl,[{sasl_error_logger, false},{error_logger_mf_dir, "/code/erlang/erlangstudy"},{error_logger_mf_maxbytes, 10485760},{error_logger_mf_maxfiles, 10}]} ].警报处理器gen_event的…

【Material-UI】Slider 组件中的 Discrete Sliders 详解

文章目录 一、Slider 组件概述1. 组件介绍2. Discrete Sliders 的特点 二、Discrete Sliders 的基本用法1. step 属性2. marks 属性3. valueLabelDisplay 属性 三、深入理解 Discrete Sliders 的配置1. 自定义刻度标记2. 限制可选值3. 设置较小的步长4. 始终显示值标签 四、应用…

Win10+GTX1050Ti安装Pytorch

目的 本文主要记录自己安装pytorch过程。 环境&#xff1a;win10 pycharm 显卡&#xff1a;GTX1050Ti 过程记录 1、确认pytorch版本 打开pytorch官网&#xff1a;https://pytorch.org/ 选择stable 2.3.0 版本&#xff0c;CUDA有11.8及12.1&#xff0c;我们看看GTX1050Ti支持…

发红包案例(java)

User类创建 public class User {private String name;private int money;public User(){}public User(String name,int money){this.namename;this.moneymoney;}public void show(){System.out.println("Name:"name" Money:"money);}public String getNam…

ruoyi-vue-pro(v3)

启动上的问题 这里第二部npm install会有问题 切换成http 解决SSL 证书问题导致的连接错误 npm config set registry http://registry.npm.taobao.org/

Zookeeper 官方示例2-SyncPrimitive 代码解读(二)

测试命令 java jar .\ZookeeperDemo-0.0.1-SNAPSHOT.jar bTest 192.168.206.100:2181 2 1. Barrier&#xff08;阻塞原语&#xff09; 1.1 概念 [!quote] A barrier is a primitive that enables a group of processes to synchronize the beginning and the end of a comput…

猫头虎 分享:Python库 NumPy 的简介、安装、用法详解入门教程

猫头虎 分享&#xff1a;Python库 NumPy 的简介、安装、用法详解入门教程 &#x1f431;&#x1f42f; 摘要 在Python编程领域&#xff0c;特别是人工智能和数据科学方向&#xff0c;NumPy库的重要性不言而喻。 作为一个强大且广泛使用的库&#xff0c;NumPy为我们提供了处理…