C#设计模式之工厂模式

 更新时间:2022年03月07日 10:49:18   作者:.NET开发菜鸟  
本文详细讲解了C#设计模式之工厂模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

这是我们用得比较多的一种设计模式,也是23种标准设计模式之一,使用前面讲的简单工厂设计模式,遇到具体产品经常变换时就不太适合了,违反了开闭设计原则;怎么才能避免修改工厂类呢?工厂方法模式可以做到。
工厂方法模式要求我们应该有一个抽象的工厂类,我们知道尽量使用抽象类或接口来定义就可以达到一个开闭原则的效果,这样我们在抽象的工厂类定义一个生产产品的方法,这个方法就是工厂方法,这也是工厂方法模式的由来,他具体的行为会有他的子类或实现类来实现。如果想生产某种产品,就定义一个新的产品,新的产品工厂类,这样就实现了不同的产品进行一个不同的创建,这样如果有信的产品,只需要添加新的工厂类,原来写好的代码不会发生变化,这种方式符合开闭原则,可扩展比较好。 

添加一个具体产品,只需要在添加一个具体产品的工厂类实现抽象工厂类,不需要修改原来的代码

示例代码:

抽象产品类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /*
       动物抽象类
     * 抽象产品
     */
    public abstract class Animal
    {
        public abstract void Eat();
    }
}

抽象工厂类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /*
      动物抽象工厂类

     */
    public abstract class AnimalFactory
    {
        public abstract Animal GetAnimal();

    }
}

生产狗的具体工厂类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 具体工厂:生成狗
    /// </summary>
   public class DogFactory :AnimalFactory
    {

        public override Animal GetAnimal()
        {
            return new Dog();
        }
    }
}

生产企鹅的具体工厂类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 具体工厂:生成企鹅
    /// </summary>
    public class PenguinFactory :AnimalFactory
    {
        public override Animal GetAnimal()
        {
            return new Penguin();
        }
    }
}

具体产品狗类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /*
       具体的产品类,实现抽象产品类
     */
    public class Dog:Animal
    {
        // 实现抽象方法
        public override void Eat()
        {
            Console.WriteLine("狗在吃饭!");
        }
    }
}

具体产品企鹅类:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /*
      具体产品类,实现抽象产品类

     */
    public class Penguin : Animal
    {
        // 实现抽象方法
        public override void Eat()
        {
            Console.WriteLine("企鹅在吃饭!");
        }
    }
}

客户端调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {
            AnimalEat(new  DogFactory());
            Console.ReadKey();
        }

        static void AnimalEat(AnimalFactory af)
        {
            Animal am = af.GetAnimal();
            am.Eat();
        }
    }
}

类图:

如果想在增加一个Cat类,只需要增加一个具体的Cat类实现Animal类的方法,增加一个具体的Cat工厂类实现抽象工厂类即可,不需要在修改已经写好的代码,符合开闭原则。

使用接口的方式实现工厂模式

需求:使用面向对象的方式设计一个系统,描述使用卡车从事货运,使用公共汽车从事客运。使用工厂模式实现。

1、汽车接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 汽车接口
    /// </summary>
    public interface ICar
    {
        /// <summary>
        /// 描述汽车从事的活动
        /// </summary>
        void Work();
    }
}

2、分别定义卡车(Truck)和公共汽车(Bus)类实现汽车接口(ICar)里面的Work()方法

Truck类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 卡车类
    /// </summary>
    public class Truck : ICar
    {
        /// <summary>
        /// 卡车从事的活动
        /// </summary>
        public void Work()
        {
            Console.WriteLine("卡车从事货运");
        }
    }
}

Bus类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 公共汽车类
    /// </summary>
    public class Bus:ICar
    {
        /// <summary>
        /// 公共汽车从事的活动
        /// </summary>
        public void Work()
        {
            Console.WriteLine("公共汽车从事客运");
        }
    }
}

3、定义汽车的工厂接口(ICarFactory):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 汽车工厂接口
    /// </summary>
    public interface ICarFactory
    {
         ICar GetCar();
    }
}

4、分别定义卡车工厂(TruckFactory)和公共汽车工厂(BusFactory)实现ICarFactory接口

TruckFactory工厂:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 卡车工厂接口
    /// </summary>
    public class TruckFactory:ICarFactory
    {
        /// <summary>
        /// 返回卡车类
        /// </summary>
        /// <returns></returns>
        public ICar GetCar()
        {
            return new  Truck();
        }
    }
}

BusFactory工厂:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    /// <summary>
    /// 公共汽车工厂
    /// </summary>
    public class BusFactory:ICarFactory
    {
        /// <summary>
        /// 返回公共汽车类
        /// </summary>
        /// <returns></returns>
        public ICar GetCar()
        {
            return new  Bus();
        }
    }
}

5、主程序调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 工厂模式
{
    class Program
    {
        static void Main(string[] args)
        {

            CarWork(new TruckFactory());
            Console.ReadKey();
        }


        /// <summary>
        /// 根据汽车工厂返回具体的汽车类
        /// </summary>
        /// <param name="cf"></param>
        static void CarWork(ICarFactory cf)
        {
            ICar c = cf.GetCar();
            c.Work();
        }
    }
}

6、程序运行结果

代码下载地址:点击下载

到此这篇关于C#设计模式之工厂模式的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#基于纯数学方法递归实现货币数字转换中文功能详解

    C#基于纯数学方法递归实现货币数字转换中文功能详解

    这篇文章主要介绍了C#基于纯数学方法递归实现货币数字转换中文功能,涉及C#针对字符串的遍历、转换与数学运算相关操作技巧,需要的朋友可以参考下
    2017-02-02
  • 浅谈c#.net中巧用ToString()将日期转成想要的格式

    浅谈c#.net中巧用ToString()将日期转成想要的格式

    有时候我们要对时间进行转换,达到不同的显示效果,更多的该怎么办呢?
    2013-03-03
  • ASP.NET总结C#中7种获取当前路径的方法

    ASP.NET总结C#中7种获取当前路径的方法

    本文主要介绍了7种获取当前路径的方法,并做了代码演示,分享给大家,感兴趣的朋友可以参考一下。
    2016-03-03
  • C#继承IList 接口的实现步骤

    C#继承IList 接口的实现步骤

    C#中的IList<T>接口是.NET框架中的一种通用接口,它定义了一组在运行时可以使用类型参数T的元素的集合,本文给大家介绍了C#继承IList 接口的设计方法,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • VS2022+unity3D开发环境搭建的实现步骤

    VS2022+unity3D开发环境搭建的实现步骤

    本文主要介绍了VS2022+unity3D开发环境搭建的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • vs2019安装和使用详细图文教程

    vs2019安装和使用详细图文教程

    这篇文章主要介绍了vs2019安装和使用详细图文教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • Unity实现滑动更换界面效果

    Unity实现滑动更换界面效果

    这篇文章主要为大家详细介绍了Unity实现滑动更换界面效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C#如何访问共享文件夹或者磁盘

    C#如何访问共享文件夹或者磁盘

    这篇文章主要为大家详细介绍了C#访问共享文件夹或者磁盘,需要用户名密码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • C#优化if...else代码的方案总结

    C#优化if...else代码的方案总结

    在编写代码实现业务需求过程中,会使用到大量的if...else 判断语句,随业务复杂程度不同,导致判断语句出现多层嵌套、多分支等情况,导致代码可读性变差、增加维护难度,本文介绍了C# 如何优化 if...else 让代码优雅起来,需要的朋友可以参考下
    2024-06-06
  • c#如何实现接口事件

    c#如何实现接口事件

    这篇文章主要介绍了c#如何实现接口事件,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-10-10

最新评论