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

2023-09-22 09:15:00

〇、简介

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):提供一个创建一系列相关或相互依赖对象的接口,而无需指定其具体类。客户端通过调用抽象工厂接口来创建一组相关的产品。适用于创建一系列相关的产品族。它在工厂模式的基础上进一步抽象,将一系列相关的产品组成一个产品族,能够方便地创建一组相关对象。同样也增加了系统的复杂度。

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

更多推荐

webpack常用配置与性能优化插件

webpack是一个流行的前端项目构建工具(打包工具),可以解决当前web开发中所面临的困境。提供了友好的模块化支持,以及代码压缩混淆、处理js兼容问题、性能优化等强大的功能,从而让程序员把工作的重心放到具体的功能实现上,提高开发效率和项目的可维护性。直接代码加注释/***各个webpack版本之间存在一定差异,经常报

ADB底层原理

介绍adb的全称为AndroidDebugBridge,就是起到调试桥的作用。通过adb我们可以在Eclipse/AndroidStudio中方便通过DDMS来调试Android程序,说白了就是debug工具。adb是androidsdk里的一个工具,用这个工具可以直接操作管理android模拟器或者真实的androi

Sftp服务安全评估

1认识SFTPFTP(SSH文件传输协议)和FTP(文件传输协议)是两种用于文件传输的协议,它们在工作原理、安全性和配置方面有很大的差异。1)工作原理:FTP:FTP使用两个独立的连接(控制连接和数据连接)来传输文件。控制连接用于发送命令和处理身份验证,而数据连接用于传输文件内容。SFTP:SFTP是通过SSH协议进行

安全基础 --- nodejs沙箱逃逸

nodejs沙箱逃逸沙箱绕过原理:沙箱内部找到一个沙箱外部的对象,借助这个对象内的属性即可获得沙箱外的函数,进而绕过沙箱前提:使用vm模块,实现沙箱逃逸环境。(vm模式是nodejs中内置的模块,是nodejs提供给使用者的隔离环境)目的:拿到process模块实现沙箱逃逸,拿到目标(1)Function构造函数实现源

求 2+22+222+2222+...+22..·22(n个2)(精确计算)

目录(1)求2+22+222+2222+...+22..·22(n个2)(精确计算)计算机组成原理与操作系统之间区别乘式还原,有乘法运算如下OOOXOO--------OOOOOOOO-------------OOOOO式中18个O位置上的数字全部是素数(2,3,5或7),请还原这算式(1)求2+22+222+2222

vue学习-02vue入门之组件

删除Vue-cli预设在用户根目录下(C:\Users\你的用户名)这个地址里有一个.vuerc文件,修改或删除配置组件Props(组件之间的数据传递)Prop的大小写(camelCasevskebab-case)不敏感Prop类型:StringNumberBooleanArrayObjectDateFunctionS

方案:AI赋能,森林防火可视化智能监管与风险预警系统解决方案

一、方案背景森林火灾是世界八大自然灾害之一,具有发生面广、突发性强、破坏性大、危险性高、处置扑救特别困难等特点,严重危及人民生命财产和森林资源安全,甚至引发生态灾难。有效预防和及时控制森林火灾是保护国家生态建设成果、推进生态文明建设的重要措施。监管痛点:1)现有的森林防火监测系统落后,以人工地面巡护、瞭望塔高点巡查为主

【群晖NAS】Synology drive套件安装设置与结合内网穿透实现远程访问——“cpolar内网穿透”

文章目录前言1.群晖SynologyDrive套件的安装1.1安装SynologyDrive套件1.2设置SynologyDrive套件1.3局域网内电脑测试和使用2.使用cpolar远程访问内网SynologyDrive2.1Cpolar云端设置2.2Cpolar本地设置2.3测试和使用3.结语前言群晖作为专业的数据

【基础篇】六、基于SpringBoot来整合SSM的案例(下)

文章目录1、前后端调用:axios发送异步请求2、添加功能3、删除功能4、修改功能5、异常消息处理6、分页功能7、分页Bug处理8、条件查询接下来加入前端页面,使用axios发送异步请求调用上篇的接口。调前端代码时,发现还挺有趣,刷新、隐藏、调用、以及一些交互逻辑的代码翻译,等框架学完看看前端的东西。1、前后端调用:a

学习视觉SLAM需要会些什么?

前言SLAM是现阶段很多研究生的研究方向,我也是作为一个即将步入视觉SLAM的研究生,网上对于SLAM的介绍很多,但很少有人完整系统的告诉你学习视觉SLAM该有那些基础,那么此贴将告诉你学习SLAM你要有那些方面的基础。文章目录前言1.经典视觉SLAM的框架2.高等数学、线性代数、概率论、矩阵论3.C++语法基础4.L

【Linux】如何使用 WSL 在 Windows 上安装 Linux

Linux如何使用WSL在Windows上安装Linux开发人员可以在Windows计算机上同时访问Windows和Linux的强大功能。通过适用于Linux的Windows子系统(WSL),开发人员可以安装Linux发行版(例如Ubuntu、OpenSUSE、Kali、Debian、ArchLinux等),并直接在W

热文推荐