当前位置:首页 >  综合要闻  > 正文

世界观速讯丨Simple Factory Pattern 简单工厂模式简介与 C# 示例【创建型】【设计模式来了】

时间:2023-05-26 22:50:46     来源:博客园
〇、简介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.Encodingusing 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 查询目标编码类型。

参考:https://www.cnblogs.com/zhili/p/SimpleFactory.html

标签:

推荐文章