Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】

这篇具有很好参考价值的文章主要介绍了Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

〇、简介

1、什么是工厂方法模式?

一句话解释:

  实体类和工厂类均为单独实现,不影响已实现的类,方便扩展。

工厂方法模式(Factory Method Pattern)是一种创建型模式,它允许客户端通过工厂方法来创建对象,而不是直接使用构造函数。这样可以让客户端代码更加灵活,同时保持实现的独立性。工厂方法可以返回同一类的对象,也可以返回不同的类对象。

官方意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。AbstractMethod 是一个类的实例化延迟到其子类。

 一个比喻:(班主任与班级)

  一个班级对应一个班主任,当插班生超额时,则需要重新组成一个班级,那么此时就需要完成一个班级的各种条件,比如一个新的教室、班主任、班级编号等,当然这个新增的班级对原有的多个班级无影响。

2、优缺点和使用场景

优点:

  • 工厂方法模式将对象的创建过程封装到了具体的工厂类中,使得客户端无需知道实际创建的具体对象是哪个类,降低了程序的耦合度
  • 通过定义抽象工厂类和具体工厂类,可以轻松添加新的产品类型,同时不影响现有代码的功能
  • 工厂方法模式可以适应开闭原则,即对扩展开放,对修改关闭。当需要增加新的产品时,只需要添加具体产品类和对应的具体工厂类即可,不必修改现有类的代码。
  • 工厂方法模式提高了代码的可测试性,因为可以通过依赖注入的方式来模拟工厂对象并创建所需的产品对象。

缺点:

  • 增加复杂性:工厂方法模式引入了额外的抽象层次,使得代码结构变得更加复杂,需要编写更多的代码。
  • 在增加新产品类型时,可能需要添加大量的新类和代码,导致系统可维护性降低。

总之,工厂方法模式是一种常用且有效的设计模式,可以提高程序的灵活性和可扩展性,但也需要在实际开发中根据具体情况进行权衡和应用。

 使用场景举例:

  • 可以用于对象的创建过程比较复杂,需要创建不同类型的对象时,将创建过程封装起来,提高代码的可维护性和灵活性。
  • 可以用于不确定对象的类别、个数或者依赖关系的情况。
  • 可以用于需要重复使用的对象(例如资源池等)的情况。
  • 可以用于测试驱动开发的框架下。

一、工厂方法模式简单实现

如下示例,先定义产品接口 IProduct 和工厂接口 IFactory,再分别进行实现:

#region 定义接口
interface IProduct
{
    void Use();
}
// 定义工厂接口  
interface IFactory
{
    IProduct CreateProduct();
}
#endregion

#region 产品 A
// 实现产品接口的具体产品类  
class ConcreteProductA : IProduct
{
    public void Use()
    {
        Console.WriteLine("使用具体产品 A");
    }
}
// 实现工厂接口的具体工厂类  
class ConcreteFactoryA : IFactory
{
    public IProduct CreateProduct()
    {
        return new ConcreteProductA();
    }
}
#endregion

#region 产品 B
class ConcreteProductB : IProduct
{
    public void Use()
    {
        Console.WriteLine("使用具体产品 B");
    }
}
class ConcreteFactoryB : IFactory
{
    public IProduct CreateProduct()
    {
        return new ConcreteProductB();
    }
}
#endregion

下边进行实际的调用:

// 工厂方法模式
IFactory factoryA = new ConcreteFactoryA();
IProduct productA1 = factoryA.CreateProduct(); // 将对象的创建进行了封装
IProduct productA2 = factoryA.CreateProduct();
productA1.Use();
productA2.Use();
IFactory factoryB = new ConcreteFactoryB();
IProduct productB = factoryB.CreateProduct();
productB.Use();
// 不用工厂方法模式的写法
ConcreteProductA concreteProductA1 = new ConcreteProductA(); // 直接创建对象
concreteProductA1.Use();
ConcreteProductA concreteProductA2 = new ConcreteProductA();
concreteProductA2.Use();
ConcreteProductB concreteProductB = new ConcreteProductB();
concreteProductB.Use();

由以上代码可见:通过工厂方法模式的实现,将对象的创建进行了封装,代码逻辑更清晰易读,当需要新增、删除或修改某个产品时,只需修改具体工厂类即可,既方便又安全。

  Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】

二、工厂方法模式的结构

根据上一章节的示例代码,简单画一个 UML 图,如下:

Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】

IProduct:定义工厂方法所创建的对象的接口。描述了一个产品的共同特征。

ConcreteProductA:实现 IProduct 接口,是具体产品的实例。

IFactory:声明工厂接口(也可以是抽象类),该接口中声明了一个工厂方法,用于创建产品。

ConcreteFactoryA:实现工厂接口的具体工厂类,通过实现方法 CreateProduct() 方法,创建具体的产品实例。每一个工厂对应一种产品。

客户端通过调用抽象工厂的工厂方法来创建产品对象,而不需要直接实例化具体产品。这样可以实现解耦,使得客户端代码与具体产品的实现分离,并且可以方便地扩展和添加新的产品变体。

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

依赖注入(Dependency Injection,简称DI)实际上是工厂方法模式的一种变体,通常与工厂方法模式一起使用。依赖注入可以帮助我们实现对象的创建和管理,使得对象的创建过程更加灵活和可控。

下面一个实例,在创建了语言接口 ILanguage、语言工厂抽象类 LanguageFactory 并实现后,又创建了一个 ClientCode 类来封装客户端代码的实现,并使用构造函数将具体工厂类作为参数传递给该类。客户端代码可以通过调用 Speak() 方法来创建相应的产品对象,并执行相关方法。

// 抽象语言类
public interface ILanguage {
   void Speak();
}
// 英语类
public class English : ILanguage {
   public void Speak() {
       Console.WriteLine("Speak English.");
   }
}
// 中文类
public class Chinese : ILanguage {
   public void Speak() {
       Console.WriteLine("说中文。");
   }
}
// 工厂方法抽象类
public abstract class LanguageFactory {
   public abstract ILanguage CreateLanguage();
}
// 英语工厂
public class EnglishFactory : LanguageFactory {
   public override ILanguage CreateLanguage() {
       return new English();
   }
}
// 中文工厂
public class ChineseFactory : LanguageFactory {
   public override ILanguage CreateLanguage() {
       return new Chinese();
   }
}
// 客户端代码
public class ClientCode {
   private readonly LanguageFactory _factory;
   public ClientCode(LanguageFactory factory) { // 依赖注入 LanguageFactory
       _factory = factory;
   }
   public void Speak() {
       ILanguage language = _factory.CreateLanguage();
       language.Speak();
   }
}
// 使用示例
static void Main(string[] args) 
{   
   ClientCode code1 = new ClientCode(new EnglishFactory()); // 依赖注入:英语工厂
   code1.Speak(); // Speak English.
   
   ClientCode code2 = new ClientCode(new ChineseFactory()); // 依赖注入:中文工厂
   code2.Speak(); // 说中文。
}

当然,如果后续有扩展需求,比如再新建一个俄语实现:

(只需增加两个独立的实现:语言接口 ILanguage、语言工厂抽象类 LanguageFactory)

// 俄语类
public class Russian : ILanguage
{
    public void Speak()
    {
        Console.WriteLine("По-русски.");
    }
}
// 俄语工厂
public class RussianFactory : LanguageFactory
{
    public override ILanguage CreateLanguage()
    {
        return new Russian();
    }
}

然后直接使用,注入俄语工厂new RussianFactory()即可输出俄语,而对原有的实现没有任何影响。

ClientCode code3 = new ClientCode(new RussianFactory()); // 依赖注入:俄语工厂
code3.Speak();

实际输出,见第三行:

  Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】

实际上在 .net 框架中,还有许多类似的用法,例如:

  • 在 ASP.NET MVC 中,可以使用 HtmlHelper 的扩展方法创建各种类型的 HTML 表单控件,如文本框、下拉框等,这些方法内部调用控件工厂来创建相应的控件对象。
  • 在 log4net 框架中,可以使用 LogManager 类的 GetLogger() 方法来获取或创建指定名称的记录器对象。
  • 使用 ADO.NET 进行数据库操作时,可以使用 DbProviderFactory 类作为通用的提供者工厂类,用来创建特定数据库提供程序的对象。通过调用 DbProviderFactories.GetFactory() 方法就可以获取该工厂类,并利用其创建具体的数据库连接、命令、数据适配器等对象。

方式都是类似的,详情自行查看源码吧。

四、相关模式

AbstractFactory 模式经常用工厂方法来实现。

工厂方法通常在 TemplateMethod 中被调用。

Prototype 原型模式不需要创建 Creator 的子类,但是,它们通常要求一个针对 Product 类的 Initialize 操作。Creator 使用 Initialize 来初始化对象,而 FactoryMethod 模式不需要这样的操作。文章来源地址https://www.toymoban.com/news/detail-463297.html

到了这里,关于Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式-抽象工厂模式(Abstract Factory Pattern)结构|原理|优缺点|场景|示例

     目录         设计模式(分类)        设计模式(六大原则)        创建型         工厂方法         抽象工厂模式        单例模式        建造者模式        原型模式      结构型         适配器模式        装饰器模式      

    2024年04月22日
    浏览(39)
  • 设计模式详解(一):工厂方法——Factory Method

    工厂方法是一种创建型设计模式。所谓创建型设计模式是说针对创建对象方面的设计模式。在面向对象的编程语言里,我们通过对象间的相互协作,共同完成复杂的业务逻辑,因而对象之间存在着依赖关系。 当对象A依赖对象B时,我们不采取直接创建对象B的方式,即 B produ

    2024年02月16日
    浏览(37)
  • 设计模式--工厂模式(Factory Pattern)

    工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但是将对象的实例化过程推迟到子类中。工厂模式允许通过调用一个共同的接口方法来创建不同类型的对象,而无需暴露对象的实例化逻辑。 工厂模式的主要目标是解耦对象的创建和使用,以及

    2024年02月10日
    浏览(37)
  • 抽象工厂模式-Abstract Factory Pattern

    原文地址:https://jaune162.blog/design-pattern/abstract-factory-pattern/ 首先我们由一个实际问题来引出抽象工厂模式。 考虑这样一个场景,系统中需要向OSS上传文件,以及通过OSS下载文件。而在系统中有不同的业务在使用这两个功能。如下图: 伪代码如下

    2024年02月20日
    浏览(37)
  • 简单工厂模式-Simple Factory Pattern

    原文地址:https://jaune162.blog/design-pattern/simple-factory-pattern/ 简单工厂模式是一种非常常用的设计模式,但是并不属于GoF中的23种设计模式。简单设计模式有很多种实现方式。 本文我们就来讨论简单工厂模式的实现方式,以及如何借助Spring实现一个扩展性很好的简单工厂模式。

    2024年02月22日
    浏览(37)
  • 抽象工厂模式(Abstract Factory Pattern)

    回顾工厂方法设计模式的不足:具体产品增加时,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度 产品等级结构:产品等级结构即产品的继承结构,即抽象产品与具体产品 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构

    2024年02月02日
    浏览(40)
  • 设计模式——抽象工厂模式(Abstract Factory Pattern)

    概述        抽象工厂模式的基本思想是将一些相关的产品组成一个“产品族”,由同一个工厂统一生产。在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性,一般情况下,一个具体工厂中只有一个或者一组重载的工

    2024年02月03日
    浏览(47)
  • 大话设计模式——2.简单工厂模式(Simple Factory Pattern)

    定义:又称静态工厂方法,可以根据参数的不同返回不同类的实例,专门定义一个类(工厂类)来负责创建其他类的实例可通过类名直接调用,被创建的实例通常具有共同的父类。 UML图: 例子: 计算器中的加减乘除,可将不同的运算看成不同的对象,通过工厂类进行构建,

    2024年02月22日
    浏览(43)
  • 【设计模式】工厂方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    【设计模式】工厂方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )_工厂方法模式的优缺点_韩曙亮的博客-CSDN博客

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包