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

C# 设计模式之工厂方法模式

总目录


前言

本文是个人基于C#学习设计模式总结的学习笔记,希望对你有用!
在简单工厂模式中说到了简单工厂模式的缺点:简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂。而工厂方法模式可以很好的规避掉这个缺点,下面就好好研究下工厂方法模式是如何做到的吧!


1 基本介绍

  1. 工厂方法模式 :一种更高级的工厂模式,具体实现由子类负责,因此更加灵活。这种设计方式符合开闭原则,即对扩展开放,对修改封闭。

工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式就可以允许系统不修改工厂类逻辑的情况下来添加新产品,这样也就克服了简单工厂模式中缺点,很好地符合了开放封闭原则(即对扩展开发,对修改封闭)。

  1. 工厂方法模式的主要角色:
    • 抽象工厂

      • 在抽象工厂类中声明了工厂方法,用于返回一个产品。提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
    • 具体产品工厂:

      • 它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,完成具体产品的创建。并可由客户端调用,返回一个具体产品类的实例。
    • 抽象产品(抽象类):

      • 定义了产品的规范,描述了产品的主要特征和功能。
      • 它是工厂类创建的所有对象的父类,封装了各种产品对象的共有方法。
    • 具体产品(实现类):

      • 它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。

2 适用场景

适用于创建对象需要大量重复的步骤,或者需要依赖于其它对象的情况,它提供了一种方式来封装多个相关或依赖对象的创建逻辑。

  • 当工厂类负责创建的对象比较多时可以考虑使用工厂方法模式

3 实现方式

接着张三的案例,张三由原先的自己做鞋子,到后来去鞋厂买鞋子,这样已经让张三特别的省事省力了,但是随着时间变化小镇子的崛起,人们越来又有钱了,小镇子里也住进来更多的人,对于鞋子的种类需求和数量需求越来越多了,之前的小鞋厂已经不能满足需求了,于是鞋厂老板大手一挥,反正这些年也挣了不少米,我们再开几个分厂,我们总厂只负责管理分厂,给分厂技术就可以了,不再负责造鞋的工作了!

假如我们有个抽象产品:鞋子(所有种类鞋子的父类),鞋子内有个抽象方法Show

	//抽象父类,抽象产品public abstract class AbstractShoes{//该方法负责输出 产品名称public abstract void Show();}

现在该产品有两个子类:LeatherShoes(皮鞋)和GymShoes(体育鞋)

    public class LeatherShoes : AbstractShoes{public override void Show(){Console.WriteLine($"我是:{nameof(LeatherShoes)} !");}}public class GymShoes : AbstractShoes{public override void Show(){Console.WriteLine($"我是:{nameof(GymShoes)} !");}}

鞋子产品这一块的代码不需要改动,主要改动在造鞋工厂。

在还是简单工厂的模式下,简单工厂是负责所有鞋子的生产,代码如下:

    //定义一个造鞋工厂类,专门负责生产鞋子public class ShoesFactory{//定义一个公有的静态方法,传入鞋子类别,然后返回一个具体类型的鞋子实例public static AbstractShoes MakeShoes(string type){if (type == "LeatherShoes"){return new LeatherShoes();}else if (type == "GymShoes"){return new GymShoes();}else{throw new ArgumentException("Invalid type.");}}}

如上面所说:随着时间变化小镇子的崛起,人们越来又有钱了,小镇子里也住进来更多的人,对于鞋子的种类需求和数量需求越来越多了,之前的小鞋厂已经不能满足需求了,于是鞋厂老板大手一挥,反正这些年也挣了不少米,我们再开几个分厂,每个厂负责制造不同的鞋子,我们总厂只负责管理分厂,给分厂技术就可以了,不再负责造鞋的工作了!

于是就有了如下的改造代码:

    //抽象工厂,负责定义实现类需要实现的方法public abstract class AbstractShoesFactory{//定义一个抽象方法//当下场景下:表示我的分厂必须都会造鞋这些技能,至于怎么造鞋,由分厂自己实现public abstract AbstractShoes MakeShoes();}//具体工厂,负责实现抽象工厂public class LeatherShoesFactory : AbstractShoesFactory{//实现父类的方法//这是一个皮鞋工厂,需要在实现具体造鞋过程public override AbstractShoes MakeShoes(){return new LeatherShoes();}}//具体工厂public class GymShoesFactory : AbstractShoesFactory{public override AbstractShoes MakeShoes(){return new GymShoes();}}

此时当张三再去买些的时候,就变成了如下的模式:

    public class ZhangSan{public void Main(){//初始化不同种类的鞋子工厂AbstractShoesFactory abstractShoesFactory1 = new LeatherShoesFactory();AbstractShoesFactory abstractShoesFactory2 = new GymShoesFactory();//用皮鞋工厂的实例,制造皮鞋AbstractShoes abstractShoes1 = abstractShoesFactory1.MakeShoes();abstractShoes1.Show();//用体育鞋工厂的实例,制造体育鞋AbstractShoes abstractShoes2 = abstractShoesFactory2.MakeShoes();abstractShoes2.Show();}}

在这里我们发现,不需要在新增一个产品的时候,去改动简单工厂内的方法(违背开闭原则);
在新增一个产品的时候,我们只需要对应新增一个新的产品类和生产该产品的工厂类即可,而不需要再去核心的工厂类中去进行代码的修改,这个符合开闭原则,对扩展开发,对修改关闭。

4 优缺点分析

简单工厂把全部的事情(变化的因素),在一个地方(类)全部处理完;而工厂方法则会定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。这样一来,扩展产品种类就不必修改工厂函数了,核心类就变成抽象类,工厂方法模式将生成具体产品的任务分发给具体的产品工厂。也就是相当于工厂总部不生产产品了,交给下辖分工厂进行生产。要增加产品类时也要相应地增加工厂类,不需要修改工厂类的代码了,这样就解决了简单工厂模式的缺点。工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

  • 优点:实现了对象的创建和使用分离且符合开闭原则,使得代码更加灵活和可维护
  • 缺点:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

结语

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


参考资料
C#设计模式(3)——工厂方法模式
C#中工厂模式详解

相关文章:

C# 设计模式之工厂方法模式

总目录 前言 本文是个人基于C#学习设计模式总结的学习笔记,希望对你有用! 在简单工厂模式中说到了简单工厂模式的缺点:简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现…...

Webpack 从入门到精通

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 一、Webpack 简介 二、Webpack 的核心概念 三、Webpack 的安装与配置 安装 Node.js 安装 Webpack 初始…...

基于VScode和C++ 实现Protobuf数据格式的通信

目录 1. Protobuf 概述1.1 定义1.2Protobuf的优势 2. Protobuf 语法3、序列号和反序列化3.1 .pb.h 头文件3.2 序列化3.3 反序列化 4、测试用例 Protobuf详细讲解链接 1. Protobuf 概述 1.1 定义 protobuf也叫protocol buffer是google 的一种数据交换的格式,它独立…...

linux环境openssl升级

1、下载openssl https://openssl-library.org/source/ 或者通过wget --no-check-certificate https://www.openssl.org/source/openssl-3.0.13.tar.gz 2、解压openssl tar -zxvf openssl-3.0.13.tar.gz 3、切换到解压后的目录 cd openssl-3.0.13/ 4、配置openssl安装目录…...

150Kg载重遥控履带式无人车技术详解

150Kg载重遥控履带式无人车是一种专为复杂地形和重载运输设计的无人化智能平台。它结合了先进的动力技术、履带式行走机构、远程遥控系统、高精度感知与导航技术及模块化设计,能够在恶劣环境下执行物资运输、侦察监视、灾害救援等多种任务。该车以其卓越的越野能力、…...

STM32的外部中断详解

一、什么是中断? 想象一下你正在家里做饭,突然门铃响了,你听到门铃声后,会暂时放下手中的事情(比如炒菜),去开门看看是谁。在这个例子中,门铃声就是一个“中断”,它打断…...

关于python问题 ,生成的excel文件内无爬取的数据存在,请问应如何解决?

🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收…...

详细介绍Avalonia中的文件操作StorageProvider服务

文章目录 一、介绍二、StorageProvider的原理三、StorageProvider的实现1. 创建文件选择和保存对话框2. 选择目录四、StorageProvider的配置五、StorageProvider的高级用法1. 读取和写入文件2. 获取文件和目录信息3. 管理文件和目录4. 处理不同平台的差异六、总结一、介绍 在桌…...

「7.31更新日志」JVS·智能BI、逻辑、规则引擎功能更新说明

项目介绍 JVS是企业级数字化服务构建的基础脚手架,主要解决企业信息化项目交付难、实施效率低、开发成本高的问题,采用微服务配置化的方式,提供了 低代码数据分析物联网的核心能力产品,并构建了协同办公、企业常用的管理工具等&am…...

编程语言 | C | 代码整理 | 4月

八月拍了拍你,并对你说:“好运就要开始了”! 目录 编程语言 | C | 代码整理 | 4月2019/4/12019/4/22019/4/22019/4/32019/4/42019/4/52019/4/62019/4/72019/4/82019/4/92019/4/102019/4/112019/4/122019/4/132019/4/142019/4/152019/4/162019…...

模板可变参数

当涉及到 C 编程中的模板参数处理时,特别是在处理可变数量的参数时,模板可变参数(variadic templates)是一个非常有用的特性。本篇博客将深入介绍模板可变参数的基本概念、语法、应用场景以及示例代码,帮助读者理解如何…...

是你!是你!我们的黄金写手!

...

QT 获取用于获取特定屏幕坐标处的最上层小部件(父与子关系的类)

QPoint globalPos pEvent->globalPos(); QWidget* widget QApplication::widgetAt(globalPos); 注意:屏幕坐标(包括显示器双屏)...

【应急响应】Linux权限维持 -隐藏权限

前言 不知攻焉知守,学会排查就要先学习如何攻击。 隐藏文件 Linux下创建一个隐藏文件:touch .test.txt 查看Linux下的隐藏文件需要用到命令:ls -al 隐藏文件时间戳 touch -r .docker hello.php 创建的hello.php文件会和.docker创建文件的时间…...

还有哪些AI应用案例目前备受关注

目前备受关注的AI应用案例众多,以下是一些代表性的例子: 1. WPS AI 背景:WPS AI是金山办公发布的基于大语言模型的人工智能办公助手,于2023年11月开启公测。 功能:WPS AI锚定AIGC(内容创作)、C…...

将控制台内容输出到文本文件

示例代码: Imports System.IO Module Module1Sub Main()Dim fs As New FileStream("D:\Desktop\test\输出结果.txt", FileMode.Create, FileAccess.Write, FileShare.None)Dim sw As New StreamWriter(fs)Console.SetOut(sw)Console.SetError(sw)For i …...

380. O(1) 时间插入、删除和获取随机元素【 力扣(LeetCode) 】

一、题目描述 实现RandomizedSet 类: RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。bool remove(int val) 当元素 val 存…...

【每日刷题】Day91

【每日刷题】Day91 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 面试题 05.07. 配对交换 - 力扣(LeetCode) 2. 面试题 08.05. 递归乘法 - 力…...

数据库索引的创建和使用

数据库索引数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度。索引优化是数据库优化的最重要手段。 如果查询语句使用索引(通常是where条件匹配索引)就会利用…...

光流传感器 - 从零开始认识各种传感器【第二十二期】

光流传感器|从零开始认识各种传感器 1、什么是光流传感器 光流传感器是一种用于测量物体相对于周围环境的运动的设备。它通过检测周围光线的变化来计算出物体的运动方向和速度,广泛应用于机器人导航、无人机飞行控制、虚拟现实等领域。 2、光流传感器是如何工作的…...

学生党福音:用最便宜的TT马达和STM32F103C8T6,我焊出了能遥控的平衡小车

低成本DIY平衡小车:TT马达与STM32的极致性价比方案 当我在宿舍里第一次看到那辆价值近千元的商业平衡小车时,脑海中立刻浮现出一个问题:能不能用更便宜的材料实现类似功能?作为一名预算有限的学生,我开始探索如何用最…...

Seraphine:英雄联盟玩家的智能数据助手,三步解锁游戏信息优势

Seraphine:英雄联盟玩家的智能数据助手,三步解锁游戏信息优势 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine 在英雄联盟的竞技世界中,信息就是力量。Seraphine是一款基于英…...

软件设计原则之OCP开闭原则

(OCP) 开闭原则 Open Closed Principle核心原则对扩展开放,对修改关闭。场景描述还是拿 UserInfo 进行举例。在开发过程中我们需要对我们使用的对象进行多步的组合操作,比如这里要打印账户和密码信息。常规的方式就是在外部直接进行调用,或者…...

开源代理解决 DeepSeek V4 与 Claude Code 的三个兼容性陷阱解决方案

在使用 Claude Code 的过程中,Anthropic 官方 API 的调用成本和网络问题一直是个痛点。DeepSeek V4 提供了兼容 Anthropic 格式的 API,价格优势明显,但实际对接时存在若干协议层面的差异,直接使用的话在进行 Agent spawn 工具调用…...

PCL 方向向量约束的RANSAC拟合平面【2026最新版】

目录 一、算法概述 二、代码实现 三、结果展示 本文由CSDN点云侠原创,博客长期更新,本文最近一次更新时间为:2026年5月10日。 一、算法概述 SampleConsensusModelPerpendicularPlane使用额外的角度约束来定义三维平面分割的模型。平面必须垂直于用户指定的轴(setAxis),直到…...

构建更优Godot MCP:AI助手与游戏开发工作流深度集成方案

1. 项目概述:为什么我们需要一个更好的Godot MCP?如果你是一个长期使用Godot引擎的开发者,尤其是当你尝试将AI能力,比如大型语言模型(LLM),集成到你的游戏开发工作流中时,你很可能听…...

手机端数据恢复神器,值得收藏

今天给大家推荐一款好用的安卓端数据恢复工具,非常好用的,还有一款Wifi信号检测工具,有需要的小伙伴及时下载收藏! 软件介绍 第一款:数据恢复大师dumpster 提到数据恢复大师,之前好像也有推荐过&#xff0…...

从“砖头”到“复活”:一个大众车机蓝牙解锁的完整逆向工程记录

从“砖头”到“复活”:一个大众车机蓝牙解锁的完整逆向工程记录 当一台原本功能完整的车载娱乐系统因为缺少关键协议握手而变成"砖头",你会怎么做?这个问题困扰着许多汽车电子爱好者和安全研究人员。本文记录了我如何通过逆向工程手…...

CSS 渐变高级技巧完全指南

CSS 渐变高级技巧完全指南 引言 CSS 渐变是现代 Web 设计中不可或缺的视觉效果,它可以创建平滑的颜色过渡,为网页增添丰富的视觉层次。本文将深入探讨 CSS 渐变的各种类型和高级技巧。 基础语法回顾 线性渐变 .linear-gradient {background: linear-grad…...

Scroll Reverser终极指南:5分钟解决macOS多设备滚动方向混乱问题

Scroll Reverser终极指南:5分钟解决macOS多设备滚动方向混乱问题 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser 你是否经常在MacBook触控板和鼠标之间切换&#xff…...