当前位置: 首页 > news >正文

C# 设计模式之抽象工厂模式

总目录


前言

工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码,而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题。


1 基本介绍

  1. 抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个种类的产品,而抽象工厂模式可生产多个种类的产品。

  2. 抽象工厂模式的主要角色:

    • 抽象工厂
      • 在抽象工厂类中声明了多个工厂方法,用于返回多个产品。提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品
    • 具体产品工厂
      • 它是抽象工厂类的子类,实现了在抽象工厂中声明的多个工厂方法,完成多个具体产品的创建。
    • 抽象产品
      • 它是定义一个产品的接口,定义了一个产品的规范,描述了一个产品的主要特性和功能。抽象工厂模式有多个抽象产品。
    • 具体产品
      • 实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
  3. 抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么。这样客户就可以从具体产品中被解耦。

  4. 抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式

2 使用场景

一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。

  • 适用于需要创建多个产品的场景
  • 抽象工厂模式一般用于严格要求以面向对象思想进行开发的超大型项目中。

3 实现方式

“绝味” 连锁店的例子来实现一个抽象工厂模式。例如,绝味鸭脖想在江西南昌和上海开分店,但是由于当地人的口味不一样,在南昌的所有绝味的东西会做的辣一点,而上海不喜欢吃辣的,所以上海的所有绝味的东西都不会做的像南昌的那样辣,然而这点不同导致南昌绝味工厂和上海的绝味工厂生成所有绝味的产品都不同,也就是某个具体工厂需要负责一系列产品(指的是绝味所有食物)的创建工作,下面就具体看看如何使用抽象工厂模式来实现这种情况。

    //抽象产品//此处为抽象鸭脖类,供不同地方的鸭脖来继承public abstract class AbstractYaBo{//展示鸭脖相关信息public abstract void Show();}//抽象产品//此处为抽象鸭舌类,供不同地方的鸭舌来继承public abstract class AbstractYaShe{public abstract void Show();}//抽象工厂//抽象工厂类,提供创建两个鸭架和鸭脖产品的接口public abstract class AbstractJueWeiFactory{// 抽象工厂提供创建一系列产品的接口// 这里作为例子,只给出了绝味中鸭脖和鸭架的生产接口public abstract AbstractYaBo MakeYaBo();public abstract AbstractYaShe MakeYaShe();}

上面我们定义了两个抽象产品类鸭架和鸭脖,然后定义了一个生产鸭脖和鸭架的抽象工厂类,现在我们需要去上海和江西南昌开分店。

上海分店:

	//上海口味的鸭脖public class ShangHaiYaBo : AbstractYaBo{public override void Show(){Console.WriteLine("上海绝味鸭脖,没那么辣");}}//上海口味的鸭舌public class ShangHaiYaShe : AbstractYaShe{public override void Show(){Console.WriteLine("上海绝味鸭舌,没那么辣");}}//上海绝味工厂 负责生产适合上海人口味的鸭脖和鸭舌public class ShangHaiJueWeiFactory : AbstractJueWeiFactory{//生产上海鸭脖public override AbstractYaBo MakeYaBo(){return new ShangHaiYaBo();}//生产上海鸭舌public override AbstractYaShe MakeYaShe(){return new ShangHaiYaShe();}}

南昌分店:

    public class NanChangYaBo : AbstractYaBo{public override void Show(){Console.WriteLine("南昌绝味鸭脖,够辣");}}public class NanChangYaShe : AbstractYaShe{public override void Show(){Console.WriteLine("南昌绝味鸭舌,够辣");}}public class NanChangJueWeiFactory : AbstractJueWeiFactory{public override AbstractYaBo MakeYaBo(){return new NanChangYaBo();}public override AbstractYaShe MakeYaShe(){return new NanChangYaShe();}}

客户端调用:

    // 客户端调用class Client{static void Main(string[] args){// 南昌工厂制作南昌的鸭脖和鸭舌AbstractJueWeiFactory nanChangFactory = new NanChangJueWeiFactory();AbstractYaBo nanChangYabo = nanChangFactory.MakeYaBo();nanChangYabo.Show();AbstractYaShe nanChangYajia = nanChangFactory.MakeYaShe();nanChangYajia.Show();// 上海工厂制作上海的鸭脖和鸭舌AbstractJueWeiFactory shangHaiFactory = new ShangHaiJueWeiFactory();shangHaiFactory.MakeYaBo().Show();shangHaiFactory.MakeYaShe().Show();Console.Read();}}

当绝味需要再在深圳再开一家分店的上海,直接按照南昌分店和上海分店一样再写一套代码就可以了。

4 优缺点分析

  • 优点

    • 抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展
    • 抽象工厂的最大好处在于交换产品系列非常方便,只需要改变具体工厂即可使用不同的产品配置。
    • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
  • 缺点

    • 抽象工厂模式很难支持新种类产品的变化。当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

5 简单工厂,工厂方法,抽象工厂对比

  • 简单工厂,工厂方法两种模式都只是针对一类产品,直接生成实例
    但是抽象工厂模式不同,抽象工厂模式并不直接生成实例, 而是用于对产品类簇的创建。
  • 通俗点来讲就是:简单工厂和工厂方法模式的工作是生产产品,那么抽象工厂模式的工作就是生产工厂的。

简单工厂把全部的事情,在一个地方(类)全部处理完,
而工厂方法却不同,其是通过创建一个框架,然后让子类决定要如何实现。
而抽象工厂则是定义一个负责创建一组产品(也就是一个产品簇)的接口


结语

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
抽象工厂模式
c#中工厂模式详解

相关文章:

C# 设计模式之抽象工厂模式

总目录 前言 工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码,而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中&#xff0c…...

Javascript前端面试基础(八)

window.onload和$(document).ready区别 window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕 window.onload 触发时机:window.onload 事件会在整个页面&#xf…...

R 语言学习教程,从入门到精通,R的安装与环境的配置(2)

1、R的安装与环境的配置 R语言是一款完全免费且开源的软件,它的开源许可证是GNU通用公共许可证(GPL),这意味着任何人都可以自由地使用、复制、修改和发布R语言的源代码,甚至可以将其用于商业用途。 和python等其他语言…...

Python批量下载音乐功能

Python批量下载音乐功能 Python批量下载音乐,调用API接口,同时下载歌曲和歌词 先安排一下要用的模块,导入进来。 import re import json import requests目录结构 下载音乐 Awking_Class.pymusic.txt 文件文件写的是音乐名字,使用换行分割 new_music 注意这个 ne…...

用 Bytebase 实现批量、多环境、多租户数据库的丝滑变更

Bytebase 提供了多种功能来简化批量变更管理,适用于多环境或多租户情况。本教程将指导您如何使用 部署配置 和 数据库组 在不同场景下进行数据库批量变更。 默认流水线 vs 部署配置 图片数据库 vs 数据库组 1. 准备 请确保已安装 Docker,如果本地没有重…...

java之方法引用 —— ::

目录 一、简介 二、引用静态方法 1.格式 2.示例 ​编辑 3.条件解析 三、引用成员方法 1.格式 2.示例 四、引用构造方法 1.格式 2.示例 五、类名引用成员方法 1.格式 2.略微不同的方法引用规则 3.示例 六、引用数组的构造方法 1.格式 2.示例 一、简介 方…...

「测试线排查的一些经验-上篇」 后端工程师

文章目录 端口占用脚本失灵线上部署项目结构模版配置文件生效 一般产品研发过程所使用的环境可分为: 研发环境-dev测试环境-test生产环境-prod 软件开发中,完整测试环境包括:UT、IT、ST、UAT UT Unit Test 单元测试 IT System Integration …...

AOSP12_BatteryStats统计电池数据信息

前言 BatteryStats模块主要用于设备在电池供电是系统对各个模块电量使用的统计,Android提供的Battery Historain工具就是对此模块统计的数据进行解析和展示。 一 BatteryStats模块类图 模块主要类图如下:见根目录的模块类图 BatteryStats:抽象类,本模块的核心类,主要定…...

【Android Studio】UI 布局

文章目录 view布局LinearLayout view 在Android开发中,View是一个非常重要的概念,它是所有用户界面组件的基类。View类及其子类构成了Android应用中的用户界面。每个View都占用屏幕上的一个矩形区域,并可以响应用户输入(如触摸、按…...

虚拟机Windows server忘记密码解决方法

原理 utilman.exe是Windows辅助工具管理器程序,‌虽然它本身不是一个关键的系统进程,‌但通过修改这个文件,‌用户可以访问一些有用的UI设置。‌在某些情况下,‌比如忘记密码需要重置时,‌通过修改utilman.exe文件为c…...

【香橙派系列教程】(六)嵌入式SQLite数据库

【六】嵌入式SQLite数据库 文章目录 【六】嵌入式SQLite数据库1.简介2.SQLite数据库安装3.SQLite命令用法1.创建数据库2.创建和查看表格3.插入查看数据(记录)4.删除更改数据(记录) 4.SQLite编程操作1.打开/创建数据库的C接口2.创建…...

深入探讨PHP8的新特性与性能优化

本文由 ChatMoney团队出品 随着互联网技术的飞速发展,PHP作为后端开发领域的热门语言也在不断演进。近期,PHP8的发布引起了广泛关注。本文将为您详细介绍PHP8的新特性以及性能优化,并通过具体示例帮助您更好地理解和应用这些新特性。 一、PH…...

2024年06月 Scratch 图形化(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch图形化等级考试(1~4级)全部真题・点这里 一、单选题(共10题,共30分) 第1题 运行下列程序,输入单词“PLAY”,最后角色说?( ) A:LY4AP B:AP4LY C:YA4PL D:PL4AY 答案:B 根据程序分析可知,首先获取单词字符数,然后奇数位的字母放在字符数左侧,偶数位…...

书生大模型全链路开源体系

书生大模型全链路开源体系 数据 预训练 微调 评测 部署 应用...

极简聊天室-websocket版(双向通信)

我们知道WebSocket是可以双向通信的,把极简聊天室代码又改了一下,前端发信息到后端也使用websocket,其实代码量更少了。。。 const express require(express); const app express(); var wsServer require(express-ws)(app)var msgs[];ap…...

从小白到架构师 | 缓存预热

缓存预热指的是在系统启动或上线前,提前将经常访问的数据加载到缓存中,以避免在系统刚启动时,用户大量请求直接访问数据库,导致数据库压力过大或系统性能下降。通过缓存预热,可以确保系统一上线就能提供快速的响应时间…...

Modbus -- TCP协议

MODBUS TCP协议是一种基于TCP/IP协议的Modbus变种,它允许Modbus协议在以太网网络上运行,使得设备之间可以通过IP网络交换数据。 一:协议概述 modbus_TCP协议:走的是网口,所以需要创建TCPclient对象进行通信,和modubus-RTU协议最大的区别是&a…...

python四舍五入取整数

在Python中,如果你想要对一个浮点数进行四舍五入并取整(即只保留整数部分),你可以使用内置的round()函数,但不指定第二个参数(即小数位数),或者明确指定为0。这样,Python…...

洛谷 P1868 饥饿的奶牛

原题 题目描述 有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。 现用汉语翻译为: 有 N 个区间,每个区间x,y 表示提供的x∼y 共y−x1 堆优质牧草。你可以选择任意区间但不…...

Arco Design 之Table表格

此篇文章为table表格示例&#xff0c;包含列、data数据、展开、选中、自定义等相关属性 基础表格 <a-table :columns"columns1" :data"tableData1" />const columns1 [{ title: "编号", dataIndex: "no"},{ title: "名称…...

抖音视频批量下载神器:3分钟搞定复杂内容管理的终极方案

抖音视频批量下载神器&#xff1a;3分钟搞定复杂内容管理的终极方案 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 抖音作为全球最受欢迎的短视频平台&#xff0c;每天产生海量的精彩内容。然而&#xff0c…...

OpenClaw沙盒体验:不装本地环境玩转GLM-4.7-Flash

OpenClaw沙盒体验&#xff1a;不装本地环境玩转GLM-4.7-Flash 1. 为什么选择沙盒体验&#xff1f; 作为一个长期关注AI自动化工具的技术爱好者&#xff0c;我一直在寻找一个既能快速验证想法又不会污染本地开发环境的方式。OpenClaw的本地部署虽然强大&#xff0c;但配置过程…...

手指划过屏幕放大模型界面,环氧树脂层和纤维基体在激光路径下呈现出清晰的物理场分布。突然发现这个双层材料烧蚀模型跑得格外顺畅——看来前几天通宵调参没白费

comsol激光清洗、烧蚀双层材料 表面一层50μm厚度的环氧树脂(可更换成其他材料)&#xff0c;基体材料为纤维材料。 添加功率为13W的激光进行清洗或烧蚀 模型非常成功、角度选择很奈斯在COMSOL里建模时有个小细节特别关键&#xff1a;把环氧树脂层的厚度参数设为全局变量。别小看…...

GME-Qwen2-VL-2B效果实测:抽象文字如何匹配具体图片?

GME-Qwen2-VL-2B效果实测&#xff1a;抽象文字如何匹配具体图片&#xff1f; 1. 多模态搜索的突破性体验 想象一下&#xff0c;你脑海中浮现出一句富有哲理的句子&#xff1a;"人生不是裁决书"&#xff0c;却想找一张能表达这种意境的图片。传统搜索引擎会怎么做&a…...

Windows虚拟控制器驱动完全指南:如何用ViGEmBus实现游戏设备模拟

Windows虚拟控制器驱动完全指南&#xff1a;如何用ViGEmBus实现游戏设备模拟 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否曾因游戏只支持特定手柄而…...

viem ABI工具使用教程:编码、解码和类型推断全攻略

viem ABI工具使用教程&#xff1a;编码、解码和类型推断全攻略 【免费下载链接】viem TypeScript Interface for Ethereum 项目地址: https://gitcode.com/gh_mirrors/vi/viem viem是一个轻量级、可组合且类型安全的TypeScript以太坊接口工具库&#xff0c;其强大的ABI工…...

Linux服务器运维:5个最容易被忽略的故障排查技巧(附实战命令)

Linux服务器运维&#xff1a;5个最容易被忽略的故障排查技巧&#xff08;附实战命令&#xff09; 在Linux服务器运维的日常工作中&#xff0c;有些故障排查点往往被工程师们忽视&#xff0c;直到问题爆发才追悔莫及。本文将揭示五个最容易被忽略但至关重要的排查技巧&#xff…...

AI 与大模型相关

一、 AI 与大模型相关 1.1 Agent&#xff08;智能体&#xff09; 定义&#xff1a;具备自主规划、工具调用、记忆管理、任务执行能力的 AI 实体&#xff0c;能主动完成复杂目标。 核心能力&#xff1a;拆解任务、调用 API / 工具、自主决策、持久记忆、后台执行。 区别&am…...

用户缓冲区与内核缓冲区原理及应用解析

1. 用户缓冲区与内核缓冲区深度解析1.1 系统架构概述现代计算机系统采用分层架构设计&#xff0c;将运行环境划分为用户空间和内核空间两个关键区域。这种划分基于处理器提供的不同执行权限级别&#xff1a;用户空间&#xff1a;运行所有用户进程&#xff0c;包括应用程序、服务…...

STM32Fx标准外设固件库下载与安装全攻略

1. STM32Fx标准外设固件库是什么&#xff1f; 对于刚接触STM32开发的工程师来说&#xff0c;标准外设固件库就像是一本"使用说明书"。它封装了芯片底层寄存器的操作&#xff0c;让我们可以用更简单的方式控制硬件。举个例子&#xff0c;如果没有固件库&#xff0c;你…...