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#设计模式之工厂模式的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Quartz.Net任务和触发器实现方法详解

    Quartz.Net任务和触发器实现方法详解

    这篇文章主要介绍了Quartz.Net任务和触发器实现方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • C#实现Winform序在系统托盘显示图标和开机自启动

    C#实现Winform序在系统托盘显示图标和开机自启动

    这篇文章主要为大家详细介绍了C#如何实现Winform序在系统托盘显示图标和开机自启动功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2025-01-01
  • C#统计字符串的方法

    C#统计字符串的方法

    这篇文章主要为大家详细介绍了C#统计字符串的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • Unity UGUI的Scrollbar滚动条组件使用详解

    Unity UGUI的Scrollbar滚动条组件使用详解

    这篇文章主要介绍了Unity UGUI的Scrollbar(滚动条)组件的介绍及使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • c#基于Redis实现轻量级消息组件的步骤

    c#基于Redis实现轻量级消息组件的步骤

    这篇文章主要介绍了c#基于Redis实现轻量级消息组件的步骤,帮助大家更好的理解和学习使用c#进行开发,感兴趣的朋友可以了解下
    2021-05-05
  • C# DataTable使用方法详解

    C# DataTable使用方法详解

    这篇文章主要为大家详细介绍了C# DataTable的使用方法,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • C#将图片和字节流互相转换并显示到页面上

    C#将图片和字节流互相转换并显示到页面上

    本文主要介绍用C#实现图片转换成字节流,字节流转换成图片,并根据图片路径返回图片的字节流,有需要的朋友可以参考下
    2015-08-08
  • C# 枚举的使用简介

    C# 枚举的使用简介

    这篇文章主要介绍了C# 枚举的简单使用,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C# task应用实例详解

    C# task应用实例详解

    这篇文章主要介绍了如何在C#中一些应用task的实例,简单易懂的代码能更好的帮你学习,有兴趣的朋友可以了解下
    2020-05-05
  • c#读取excel内容内容示例分享

    c#读取excel内容内容示例分享

    这篇文章主要介绍了c#读取excel内容内容示例,要求Excel需是.xls格式,需要的朋友可以参考下
    2014-03-03

最新评论