首页 > 编程语言 >Factory Design Pattern in C#

Factory Design Pattern in C#

时间:2023-01-24 21:25:20浏览次数:40  
标签:Animal C# Pattern 工厂 typeName Design animal 设计模式 客户端

一、什么是工厂设计模式?

根据Gang of Four所述,工厂是用于创建其他对象的对象,就是说工厂是一个带有方法的类,该方法将根据输入的参数创建并返回不同类型的对象。简单地说,如果我们有一个父类和n个子类,并且基于提供的数据,必须创建并返回其中一个子类的对象,那么就需要使用工厂设计模式。

在工厂设计模式中,我们创建一个对象,而不向客户端公开对象创建逻辑,客户端将使用公共接口引用新创建的对象,也就是接口指向某一个实现类。工厂设计模式背后的基本原则是,在运行时,我们根据传递的参数获得对应的对象。

二、理解工厂设计模式

定义接口以及实现类:

public interface Animal
{
    string GetAnimalInfo();
}
public class Dog : Animal
{
    public string GetAnimalInfo() => "泰迪犬";
}
public class Cat : Animal
{
    public string GetAnimalInfo() => "波斯猫";
}

用户需要获取某一个动物的详细信息,如果不用工厂模式,客户端端代码需要如下代码编写方式:

Animal? animal = null;
var typeName = "dog";
if (typeName == "dog")
    animal = new Dog();
else if (typeName == "cat")
    animal = new Cat();

if (animal is not null)
    Console.WriteLine(animal.GetAnimalInfo());
else
    Console.WriteLine("Invalid type name");

代码非常简单,拿到类型名称,然后使用 if-else 条件创建适当的 Animal实例,然后调用GetAnimalInfo()获取详细信息。
上述代码实现的问题是什么?

  • 首先,客户端类(Program)和相关动物类(Dog、Cat)之间的紧密耦合。
  • 其次,如果我们添加一个新的动物类,那么我们也需要通过添加一个额外的 if-else 条件来修改Main方法,这个条件不仅在开发过程中,而且在测试过程中都会产生开销。

而通过使用工厂设计模式就可以克服上述问题。

根据工厂设计模式的定义,工厂设计模式创建对象时不向客户端公开对象创建逻辑,而客户端使用公共接口引用新创建的对象。

Step1:创建工厂类

public class AnimalFactory
{
    public static Animal? GetAnimal(string typeName)
    {
        Animal? animal = null;
        if (typeName == "dog")
            animal = new Dog();
        else if (typeName == "cat")
            animal = new Cat();
        return animal;
    }
}

Step2:修改主方法调用代码

var typeName = "dog";
Animal? animal = AnimalFactory.GetAnimal(typeName);
if (animal is not null)
    Console.WriteLine(animal.GetAnimalInfo());
else
    Console.WriteLine("Invalid type name");

如上代码所示,客户端需要创建对象,直接调用工厂方法并传入类型名称即可,GetAnimal方法将会创建并返回对应的对象实例给客户端。

三、工厂模式的真实例子

真实世界中,可以说工厂是产品生产的地方,或者说它是一个创造产品的集中地。然后,根据接收到的订单,由工厂交付适当的产品。例如,一个汽车工厂可以生产不同类型的汽车。如果你向汽车工厂订购汽车,那么根据你的要求或规格,工厂将创建适当的汽车,然后交付给你。

同样,在工厂设计模式中。工厂(即类)将根据传入的参数创建和交付产品(即对象)。

四、在实际项目开发中何时使用工厂设计模式?

在由客户端创建对象时指定确切的类名并不是一种好的编程方法,因为这会导致客户端和产品之间的紧密耦合。为了克服这个问题,需要使用工厂设计模式。这种设计模式为客户端提供了的简单机制来创建对象。所以,在遇到如下三种情况时,可考虑使用工厂设计模式:

  1. 对象需要延申到某一个子类。
  2. 不知道要创建哪些确切的子类。
  3. 具体实现将随着时间的推移而变化,而客户端将保持不变。

五、简单工厂模式存在的问题

  1. 如果我们需要添加任何新的子类 ,那么我们需要在AnimalFactory类的GetAnimal方法中添加一个新的 If else 条件。这违反了开放/封闭设计原则。
  2. 我们还在工厂类和产品类之间建立了紧密耦合。

标签:Animal,C#,Pattern,工厂,typeName,Design,animal,设计模式,客户端
From: https://www.cnblogs.com/dcy521/p/17066392.html

相关文章

  • 【LeetCode哈希表#2】两个数组的交集(Set+数组)
    两个数组的交集力扣题目链接(opensnewwindow)题意:给定两个数组,编写一个函数来计算它们的交集。说明:输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的......
  • 0315-Java学习-091-【答疑解惑】Failed to configure a DataSource: 'url' attribute
    一、问题现象 创建了一个springboot项目后,运行项目提示信息如下所示 相应的文本信息如下: Description:FailedtoconfigureaDataSource:'url'attributei......
  • 0316-Java学习-092-【答疑解惑】Unknown lifecycle phase ".test.skip=true".
    一、问题描述:在IDEA的“Terminal”控制台执行如下命令报错:Unknownlifecyclephase".test.skip=true".mvncleanpackage-Dmaven.test.skip=true 错误日志详......
  • caddyserver step-ca 集成
    最近在学习caddy2的一些新特性,以前大致看过step-ca这个强大的证书管理工具,所以集成caddy+step-ca的acme进行测试下因为acme需要对于dns进行校验,但是因为自己是本地......
  • LeetCode-670. 最大交换-题解分析
    题目来源670.最大交换题目详情给定一个非负整数,你至多可以交换一次数字中的任意两位。返回你能得到的最大值。示例1:输入:2736输出:7236解释:交换数字2和数字......
  • python进程绑定CPU的意义
        ===================================== 相关:python进程绑定CPU的一些Demo【转载】python进程绑定CPU......
  • 题解 ARC154D【A + B > C ?】
    显然\(1+1>x\)对任意大于\(1\)的正整数\(x\)都不成立。利用这一点,我们可以在\(n-1\)次询问内问出\(1\)的位置。具体地,首先假设\(p_1\)为\(1\),记我们假设的为......
  • postgresql/lightdb中WHERE CURRENT OF的使用
    最近看PG源码,在语法分析中有看到CURRENTOF元素。在PG游标中,WHERECURRENTOF可以用来使用游标更新或删除当前指向的行。语法:UPDATEtableSET...WHERECURRENTOFcurs......
  • 路由器功能------BFD (Bidirectional Forwarding Detection)双向转发检测
    原理:1.状态迁移BFD会话建立遵循三次握手,BFD有四种状态:Down:会话处于Down或者刚刚创建Init:已经能够与对端系统通信,本端希望使会话进入Up状态Up:会话已经建立AdminDown:会......
  • CF1726D 题解
    EdgeSplit。一开始nt了,以为红边为一颗树,蓝边为剩余边,蓝边就不会有环了。假设有\(n\)个点,\(m\)条边,且这些边没有出现环,那么连通块的数量为\(n-m\),因为不存在环,......