Simple Factory 简单工厂模式简介与 C# 示例【创建型3.1】【设计模式来了_3.1】

news2024/11/23 16:14:01

〇、简介

1、什么是简单工厂模式?

一句话解释:

  客户类和工厂类严格分工,客户类只需知道怎么用,处理逻辑交给工厂类。

简单工厂模式(Simple Factory Pattern)是日常开发中常用的设计模式。其是一种简单的创建型模式,它通过一个工厂类来创建对象,客户端只需要知道如何使用工厂类,而不需要知道对象的实现细节。工厂类负责创建对象的整个生命周期,并且负责处理与具体实现有关的逻辑。

这种将变化逻辑和客户端分离的方式,就是面向对象中的“封装”特性了。

 一个比喻:(食堂与学生)

  比如一个食堂中午有各种面食,学生也就是客户端,关心的是菜单想吃哪个就给直接说,不关心这份焖面或者烩面怎么做的,后厨就相当于工厂类,把控着制作的步骤。

2、优缺点和使用场景

  • 优点:简单工厂模式可以使客户端代码变得简洁,同时隐藏对象的实现细节。
  • 缺点:当需要增加新的运算类时,需要修改工厂类的代码,这违反了开闭原则。此外,工厂类包含了一组相关对象的创建逻辑,这使得工厂类变得复杂,难以维护。

 使用场景举例:

  • 客户端如果对于如何创建对象的逻辑不关心,且知道工厂类的入参时,可以考虑使用简单工厂模式。
  • 当工厂类负责创建的对象比较少时可以考虑使用简单工厂模式,因为比较多的话 case 太多维护起来较麻烦。

二、简单工厂模式的简单实现与比较

 如下代码,是一个画形状的示例:

 
// 形状接口,画动作的方法
public interface IShape
{
void Draw();
}
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("画圆:〇");
}
}
public class Rectangle : IShape
{
public void Draw()
{
Console.WriteLine("画方:口");
}
}
public class ShapeFactory // 简单工厂实现
{
public static IShape CreateShape(string shapeType)
{
switch (shapeType) // 当需要扩展时,就需要修改这里的 case 也是本模式的缺点所在
{
case "圆":
return new Circle();
case "方":
return new Rectangle();
default:
throw new ArgumentException("输入形状不支持!");
}
}
}

测试代码: 

 
static void Main(string[] args)
{
// 简单工厂模式写法
IShape circle = ShapeFactory.CreateShape("圆"); // 把对象的创建交给工厂类
circle.Draw();
IShape rectangle = ShapeFactory.CreateShape("方");
rectangle.Draw();
// 不用简单工厂模式的写法
Circle circle = new Circle(); // 单个类实例化,把创建对象的工作放在了客户端
circle.Draw();
Rectangle rectangle = new Rectangle();
rectangle.Draw();
}

结果是相同的:

   

三、在 .NET 框架中的实际应用

 .NET 中 System.Text.Encoding 类就实现了简单工厂模式,该类中的 GetEncoding(int codepage) 就是工厂方法,具体的代码可以通过 ILSpy 反编译工具进行查看,下面就是该方法中的代码:

 
// System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
// System.Text.Encoding
using System.Globalization;
public static Encoding GetEncoding(int codepage)
{
Encoding encoding = FilterDisallowedEncodings(EncodingProvider.GetEncodingFromProvider(codepage));
if (encoding != null)
{
return encoding;
}
switch (codepage)
{
case 0:
return Default;
case 1200:
return Unicode;
case 1201:
return BigEndianUnicode;
case 12000:
return UTF32;
case 12001:
return BigEndianUTF32;
case 65001:
return UTF8;
case 20127:
return ASCII;
case 28591:
return Latin1;
case 1:
case 2:
case 3:
case 42:
throw new ArgumentException(SR.Format(SR.Argument_CodepageNotSupported, codepage), "codepage");
case 65000:
{
if (LocalAppContextSwitches.EnableUnsafeUTF7Encoding)
{
return UTF7;
}
string p = string.Format(CultureInfo.InvariantCulture, "https://aka.ms/dotnet-warnings/{0}", "SYSLIB0001");
string message = SR.Format(SR.Encoding_UTF7_Disabled, p);
throw new NotSupportedException(message);
}
default:
if (codepage < 0 || codepage > 65535)
{
throw new ArgumentOutOfRangeException("codepage", SR.Format(SR.ArgumentOutOfRange_Range, 0, 65535));
}
throw new NotSupportedException(SR.Format(SR.NotSupported_NoCodepageData, codepage));
}
}
public abstract class Encoding : ICloneable
{
// 。。。
}

 由源码可知,GetEncoding(int) 方法中,例举了全部可用的编码方式,客户端这可以通过编码 codepage 查询目标编码类型。

四、简单工厂、工厂方法和抽象工厂模式的关系

三者都属于创建型设计模式,都关注对象的创建,但在实现方式和应用场景上有一些区别。

相同点:

  • 都是创建对象的设计模式,将对象的实例化过程封装起来。
  • 通过使用这些模式,可以提供灵活性和可维护性,降低了代码的耦合度。

区别:

  • 简单工厂(Simple Factory):由一个工厂类根据传入的参数来决定创建哪种产品的实例。客户端只需要与工厂类交互,不需要直接实例化具体产品。适用于创建单一类型的产品。优点是简单易懂,适用于只有少量产品的情况,但缺点是扩展性较差,添加新产品时需要修改工厂类。
  • 工厂方法(Factory Method):定义一个创建产品的接口,由子类来决定具体实例化哪个产品。客户端通过调用工厂方法来获取产品实例。适用于创建一组相关或相似的产品。它通过使用继承或实现接口的方式来实现产品的创建,提供了更好的扩展性和灵活性,但也增加了代码的复杂度。
  • 抽象工厂(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定其具体类。客户端通过调用抽象工厂接口来创建一组相关的产品。适用于创建一系列相关的产品族。它在工厂模式的基础上进一步抽象,将一系列相关的产品组成一个产品族,能够方便地创建一组相关对象。同样也增加了系统的复杂度。

简单工厂模式适用于只有少量产品且不经常变动的情况,而工厂方法模式和抽象工厂模式适用于需要创建多个相关或相似产品的情况

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1034698.html

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

相关文章

【WSN】基于蚁群算法的WSN路由协议(最短路径)消耗节点能量研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

postgresql-存储过程

postgresql-存储过程 简述PL/pgSQL 代码块结构示例嵌套子块 声明与赋值控制结构IF 语句CASE 语句简单case语句搜索 CASE 语句 循环语句continuewhilefor语句遍历查询结果 foreach 游标游标传参 错误处理报告错误和信息检查断言 捕获异常自定义函数重载VARIADIC 存储过程示例事务…

Opencv-python去图标与水印方案实践

RGB色彩模式是工业界的一种颜色标准&#xff0c;是通过对红&#xff08;R&#xff09;、绿&#xff08;G&#xff09;、蓝&#xff08;B&#xff09;三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的&#xff0c;RGB即是代表红、绿、蓝三个通道的颜色&#xff…

【虚拟化】虚拟机vcpu绑核物理机

文章目录 一、NUMA二、虚拟机xml配置解析 参考文章 第一篇&#xff1a;KVM虚拟化CPU技术总结 第二篇&#xff1a;虚机cpu和mem的配置&#xff08;cputune和numatune&#xff09; 第三篇&#xff1a;libvirt 中cpu, numa 的配置 第四篇&#xff1a;如何提高虚拟机性能&#xff1…

最新研究综述——探索基础模型中的“幻觉”现象

深度学习自然语言处理 原创作者&#xff1a;Winnie “幻觉”问题即模型生成的内容可能包含虚构的信息。它不仅在大语言模型(LLMs)中存在&#xff0c;也存在于图像、视频和音频等其他一系列基础模型中。 针对这一问题&#xff0c;一篇最近的综述论文对目前所有基础模型的“幻觉”…

树、二叉树、堆及其应用(堆排序、top-k问题)

目录 树的概念与结构 概念&#xff1a; 与树相关的概念: 树的表示&#xff1a; 二叉树 概念&#xff1a; 特殊的二叉树&#xff1a; 二叉树性质&#xff1a; 二叉树的存储结构&#xff1a; 堆 堆的概念: 堆的实现&#xff1a; 堆的创建&#xff1a; 堆的插入&#xff1a; 堆的删…

linux、windows的pip一键永久换源[清华源、中科大、豆瓣、阿里云]

前言 本文概述&#xff1a;linux、windows操作系统一键将pip下载源永久设置为国内下载源&#xff0c;避免了使用临时源需要到处找镜像地址的麻烦。 作者介绍&#xff1a;作者本人是一名人工智能炼丹师&#xff0c;目前在实验室主要研究的方向为生成式模型&#xff0c;对其它方向…

stm32_标准库_中断_按键点灯|蜂鸣器

配置流程 需要对AFIO、EXTI、NVIC、GPIOB进行配置形成通路将中断连接至CPU APB2总线连接的寄存器 LED灯代码 #include "stm32f10x.h" // Device header #include "Delay.h"GPIO_InitTypeDef GIPO_InitStruct;//结构体配置GPIO EXTI_InitTypeDef EXTI_…

海普纯化产品-多肽固相合成载体

#海普纯化产品-多肽固相合成载体 多肽固相合成法被广泛应用于多肽和蛋白质的研究领域&#xff0c;特别是短多肽的合成&#xff0c;随着全新化学结构的新药开发难度加大&#xff0c;投入费用逐年增高&#xff0c;多肽类药物的开发逐渐成为医药领域的新热点。 多肽类药物合成技术…

【Redis】专栏合集,从入门到高级业务场景实战

作者简介 目录 1.概述 2.下载安装 3.基础操作 4.集群 5.实战场景 1.概述 诸如数mysql、Oracle之类的关系型数据库或者NTFS、HDFS之类的文件存储系统&#xff0c;其本质上数据都是存在磁盘上的。这是现代计算机体系架构的架构所决定的&#xff0c;要持久化存储的数据都会落…

一文带你实现从PDF到Word文件的相互转换

一文带你实现从PDF到Word文件的相互转换 01. 前期准备 模块安装 pip install pdf2docx or使用国内镜像源进行安装&#xff08;清华的镜像源&#xff09; pip install pdf2docx -i https://pypi.tuna.tsinghua.edu.cn/simple 02. 模块介绍 pdf2docx是一个Python模块&#xff0…

SpringBoot源码解析: 从手写一个简易版SpringBoot开始

IDE&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 文章目录 真正的SpringBoot手写一个简易版的springboot一. 准备1.1 准备自定义的springboot模块1.2 准备用户模块User 二. 运行测试2.1 第一次运…

如何快速上传批量剪辑的素材?附素材水印、字幕去除教程

想要快速上传网络素材&#xff0c;大家可以使用超级编导批量剪辑软件。 首先进入超级编导官网&#xff0c;免费下载超级编导超级编导软件&#xff0c;可以在官网中添加产品顾问&#xff0c;获取试用账号&#xff0c;登录即可开始使用。 超级编导支持批量上传URL链接到后台&…

Manifest merger failed

编译报错&#xff1a;Manifest merger failed with multiple errors 定位编译错误&#xff1a;java.lang.RuntimeException: Manifest merger failed with multiple errors 近日&#xff0c;项目中需要引入一个module。在成功导入后&#xff0c;添加依赖到主模块上&#xff0c…

【RocketMQ】(六)顺序消息实现原理

全局有序 在RocketMQ中&#xff0c;如果使消息全局有序&#xff0c;可以为Topic设置一个消息队列&#xff0c;使用一个生产者单线程发送数据&#xff0c;消费者端也使用单线程进行消费&#xff0c;从而保证消息的全局有序&#xff0c;但是这种方式效率低&#xff0c;一般不使用…

955. 删列造序 II;1838. 最高频元素的频数;1392. 最长快乐前缀

955. 删列造序 II 核心思想&#xff1a;我们可以按照一行一行排列strs&#xff0c;删除索引序列就代表删除某一列&#xff0c;那么我们如何判断一列是否应该删除呢&#xff0c;我们可以从反方向思考&#xff0c;应该保留那些列呢&#xff1f;从第一列开始&#xff0c;如果它不…

WebGIS面试题(浙江中海达)

1、Cesium中有几种拾取坐标的方式&#xff0c;分别介绍 Cesium是一个用于创建3D地球和地理空间应用的JavaScript库。在Cesium中&#xff0c;你可以使用不同的方式来拾取坐标&#xff0c;以便与地球或地图上的对象进行交互。以下是Cesium中几种常见的拾取坐标的方式&#xff1a…

jdk21(最新版) download 配置(linux window mac)

download 直达链接 jdk21,17 # wget https://download.oracle.com/java/20/latest/jdk-21_linux-x64_bin.deb # 选择你需要的包类似格式替换包的名称就可以实现终端下载jdk下载登录/oracle账号 下载jdk有可能存在要求登录帐号的情况 # 好心人的帐号 账号&#xff1a; 599…

C语言内存函数的使用、剖析及模拟实现

目录 一、内存拷贝函数——memcpy 1.函数声明&#xff1a; 注意&#xff1a; 2.函数使用用例&#xff1a; 3.memcpy函数的模拟实现&#xff1a; 二、内存拷贝函数2——memmove 1.函数声明&#xff1a; 2.memmove函数的模拟实现 三、内存比较函数——memcmp 1.函数声明…

01_docker镜像管理:80分钟一口气学完docker+k8s!带你掌握docker+k8s所有核心知识点,全程干货,无废话!

docker镜像的实际使用学习 开发过程中&#xff0c;需要安装很多三方工具&#xff0c;比如etcd、kafka、mysql、nginx等等 1、下载安装Docker工具。 2、获取该软件的Docker镜像&#xff08;基本上&#xff0c;都能搜索到核实的镜像&#xff09;&#xff0c;下载镜像nginx镜像…