当前位置: 首页 > 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: "名称…...

Python机器学习 模型

Python机器学习模型、回归预测模型、数据清洗、数据处理、数据挖掘、数据分析代做。 模型不仅限于线性回归、逻辑回归、决策树、SVM、随机森林、贝叶斯、XGBoost、LightGBM、CatBoost&#xff0c;聚类&#xff1a;K-Means、DBSCAN&#xff0c;机器学习都可。 时间序列分析&…...

基于 STM32 的 NAS私有云盘搭建:集成LwIP 协议、HTTP/HTTPS、WEB前端技术栈(代码示例)

项目概述 在本项目中&#xff0c;我们将搭建一个基于 STM32 的 NAS&#xff08;网络附加存储&#xff09;私盘&#xff0c;通过网络访问存储在外部 SATA 硬盘上的文件。该项目将使用 STM32 开发板、外接 SATA 硬盘、LwIP 协议栈以及 FATFS 文件系统来实现文件的上传、下载和管…...

蓝屏?死机?爆CPU?多开卡顿?你有关心过你的硬盘吗?

上来先叠甲 蓝屏、死机、爆cpu、多开卡顿&#xff0c;不一定是硬盘的问题&#xff0c;只是硬盘有问题都可能会引起这些现象&#xff0c;所以不要遇到这些问题就一定认为是硬盘的问题然后说我说的&#xff0c;只是给你一个排除问题的思路。本文会采用比较通俗所以不太专业的角度…...

Flutter开发报错error: unable to unlink old ‘pubspec.yaml‘: Invalid argument

背景&#xff1a;主分支master&#xff0c;然后每人1个分支&#xff0c;每次push到自己分支后&#xff0c;再提mr到master。 于是每次提交前要先git merge origin/master。 有时候会报这个错误&#xff0c;无法merge 原因&#xff1a;很简单&#xff0c;就是pubspec.yaml这个文…...

零基础进程最详解:进程状态、僵尸进程、孤儿进程、阻塞态、挂起态、进程切换、进程常用命令、进程创建、队列优先级

目录 强烈建议全文阅读&#xff01;&#xff01;&#xff01; 强烈建议全文阅读&#xff01;&#xff01;&#xff01; 强烈建议全文阅读&#xff01;&#xff01;&#xff01; 一、进程状态 二、僵尸和孤儿进程 1、僵尸进程 Z&#xff08;zombie&#xff09; 2、孤儿进…...

Redis的分布式锁

目录 一、定义与原理 基于Redis的分布式锁 获取锁 释放锁 锁误删问题&#xff1a;因为key值一样,将别人的锁删掉了 锁误判问题二&#xff1a;判断锁和释放锁不是原子性的 Lua脚本 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁 分布式锁的优点…...

C++笔记---类和对象

1. 类的定义 类是C中的一种自定义类型&#xff0c;是某个具体事物或概念的抽象化代码表示&#xff0c;通过类的成员&#xff08;变量函数/方法&#xff09;&#xff0c;可以表征出事物或概念的特征。 1.1 类定义的格式 class Stack { public:// 成员函数void Init(int n 4)…...

全国区块链职业技能大赛样题第9套后端源码

后端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746050 前端源码地址:https://blog.csdn.net/Qhx20040819/article/details/140746216 智能合约+数据库表设计:https://blog.csdn.net/Qhx20040819/article/details/140746646 项目预览 登录 用户管理...

3个功能强大的PDF转换工具,免费试用

给大家分享3个功能强大能满足更高需求的PDF转换工具&#xff0c;都提供免费的试用机会。 1.嗨动PDF编辑器 一款多功能的PDF编辑软件&#xff0c;集PDF阅读、PDF转换、PDF编辑功能为一体。支持转换的格式多样&#xff0c;转换速度快&#xff0c;转换后的排版和内容与原文保持一…...

表单修改数字输入框保留小数点

1.在表单设计打开修改的表单 2.打开需要修改的字段 3.按F12&#xff0c;进入“开发模式” 4.开启“开发者工具”左上角检索工具 开启&#xff1a;鼠标左键点击&#xff0c;当图标颜色为蓝色 关闭&#xff1a;鼠标左键点击&#xff0c;当图标颜色为灰色 5.鼠标移动到需要修改的…...

wordpress可以做外贸/媒体软文推广平台

第七章 确保Web安全的HTTPS1、HTTP的不足通信使用明文&#xff08;不加密&#xff09;&#xff0c;内容可能被监听 不验证通信方的身份&#xff0c;因此可能遭遇伪装 无法验证报文的完整性&#xff0c;所以有可能已遭篡改 2、通信加密1 通信的加密 2 内容的加密 3、通过查看对手…...

一个产品有两个品牌怎么做网站/公司网站如何seo

一、ls定义及语法 ls&#xff1a;ls命令用于列出指定工作目录下之内容&#xff08;包括文件和目录&#xff09;。 语法&#xff1a;ls 参数 路径  --参数可选 二、参数及实例讲解 不带参数&#xff1a;显示指定目录的文件和目录&#xff08;不包含隐藏属性的文件和目录&#…...

永久网站/搜索引擎营销的英文缩写

1.中断屏蔽方法 利用 “开/关中断指令” 实现&#xff08;与原语的实现思想相同&#xff0c;即在某进程开始访问临界区到结束访问为止都不允许中断&#xff0c;也就不能发生进程的切换&#xff0c;因此也不可能发生两个进程同时访问临界区的情况&#xff09; 2.TestAndSet方法…...

自己做的网站怎么爬数据/搜索引擎推广的常见形式有

说起独立博客的技术演变&#xff0c;从数据库到纯文本放git是一大进步&#xff0c;从HTML到markdown又是一大进步。 解析技术有没有进步呢&#xff1f;既然markdown是纯文本了&#xff0c;再用PHP/Python/Ruby去实时解析&#xff0c;多么多此一举啊&#xff08;比如github用的J…...

wordpress文章页多个产品图/深圳seo关键词优化

不走索引的其它原因&#xff1a;    1、建立组合索引&#xff0c;但查询谓词并未使用组合索引的第一列&#xff0c;此处有一个INDEX SKIP SCAN概念。    2、在包含有null值的table列上建立索引&#xff0c;当时使用select count(*) from table时不会使用索引。    …...

移动端网站搭建/竞价托管怎么做

Spring boot 是 Spring 的一套快速配置脚手架&#xff0c;可以基于spring boot 快速开发单个微服务&#xff0c;Spring Boot&#xff0c;看名字就知道是Spring的引导&#xff0c;就是用于启动Spring的&#xff0c;使得Spring的学习和使用变得快速无痛。不仅适合替换原有的工程结…...