当前位置: 首页 > 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#中工厂模式详解

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 定时器知识点
  • Go语言加Vue3零基础入门全栈班15 gin+gorm+vue3用户管理系统实战录播课 2024年08月04日 课程笔记
  • Python爬虫与MongoDB的完美结合
  • 《零散知识点 · 自定义 HandleMapping》
  • 鸿蒙媒体开发【相机数据采集保存】拍照和图片
  • 大模型术语表
  • 24年第五届“华数杯”数学建模竞赛浅析
  • 利用ffmpeg转码视频为gif图片,调整gif图片的大小
  • 全球氢燃料电池汽车市场规划预测:未来六年CAGR为44.4%
  • 前端-防抖代码
  • App推广新利器:Xinstall携带参数安装功能详解
  • FIR低通滤波器
  • 可验证随机函数 vrf 概述
  • Boost:asio网络编程从同步到异步
  • 【C++】函数重载
  • [LeetCode] Wiggle Sort
  • 【翻译】babel对TC39装饰器草案的实现
  • Android 控件背景颜色处理
  • CentOS从零开始部署Nodejs项目
  • Git学习与使用心得(1)—— 初始化
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • LeetCode18.四数之和 JavaScript
  • MYSQL 的 IF 函数
  • Puppeteer:浏览器控制器
  • spring boot下thymeleaf全局静态变量配置
  • 百度小程序遇到的问题
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 简单实现一个textarea自适应高度
  • 通信类
  • 一份游戏开发学习路线
  • 一个项目push到多个远程Git仓库
  • 赢得Docker挑战最佳实践
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #FPGA(基础知识)
  • $$$$GB2312-80区位编码表$$$$
  • $jQuery 重写Alert样式方法
  • (2)STL算法之元素计数
  • (31)对象的克隆
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (ros//EnvironmentVariables)ros环境变量
  • (八)c52学习之旅-中断实验
  • (十三)Flask之特殊装饰器详解
  • (小白学Java)Java简介和基本配置
  • (一)kafka实战——kafka源码编译启动
  • (一)WLAN定义和基本架构转
  • (游戏设计草稿) 《外卖员模拟器》 (3D 科幻 角色扮演 开放世界 AI VR)
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • (自用)仿写程序
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .bashrc在哪里,alias妙用
  • .gitignore文件—git忽略文件
  • .Net Core 中间件与过滤器