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#設計模式之工廠模式的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: