1. 程式人生 > >設計模式(C#)——工廠模式

設計模式(C#)——工廠模式

推薦閱讀:

      在簡單工廠模式中講到簡單工廠模式的缺點:難以擴充套件,一旦新增新運算就必須修改簡單工廠方法。
      工廠方法模式:定義一個用於建立物件的介面,讓子類決定例項化哪一個類。工廠模式使其建立過程延遲到子類進行。把具體產品的建立推遲到子類中,此時工廠類不再負責所有產品的建立,而只是給出具體工廠必須實現的介面。
 工廠模式要素:

1、抽象工廠(Creator):是工廠方法模式的核心角色,任何在模式中建立的物件的工廠類必須實現這個介面;

2、具體工廠(Concrete Creator):這是實現抽象工廠介面的具體工廠類,包含與應用程式密切相關的邏輯,並且受到應用程式呼叫以建立產品物件;

3、抽象產品(Product):工廠方法模式所建立的物件的基類,也就是產品物件的共同父類或共同擁有的介面;

4、具體產品(Concrete Product):這個角色實現了抽象產品角色所定義的介面。

下面舉個例子用類圖來介紹一下上面幾個要素之間的關係吧。
 在這裡插入圖片描述
      名稱空間工廠方法模式中包含抽象工廠Factory、具體工廠LeiFactory 、抽象產品Volunteer,具體產品Leifeng 。本案例將向大家展示如何使用簡單工廠模式來進行不同的算術運算。
程式碼實現過程:
1.建立抽象類Volunteer

abstract class Volunteer
{
    public abstract void sweep();//掃地
    public abstract void cook();//煮飯
    public abstract void wash();//洗衣服
}

2.建立具體產品Leifeng

class Leifeng : Volunteer
{
    public override void sweep()
    {
        Console.WriteLine("雷鋒掃地");
    }
    public override void cook()
    {
        Console.WriteLine("雷鋒煮飯");
    }
    public override void wash()
    {
        Console.WriteLine("雷鋒洗衣");
    }
}

3.建立抽象工廠Factory

abstract class Factory
{
    public abstract Volunteer getvol();
}

4.建立具體工廠LeiFactory

class LeiFactory : Factory
{
    public override Volunteer getvol()
    {
        return (new Leifeng());
    }
}

5.使用該工廠,通過傳遞型別資訊來獲取實體類的物件。

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

namespace 工廠方法模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Factory fact = new LeiFactory();
            Volunteer lei = fact.getvol();
            lei.cook();
            lei.sweep();
            lei.wash();

            fact = new UniFactory();
            lei = fact.getvol();
            lei.cook();
            lei.sweep();
            lei.wash();
        }
    }
}

從上面程式碼可以發現:
優點:
1、一個呼叫者想建立一個物件,只要知道其名稱就可以了。
2、擴充套件性高,如果想增加一個產品,只要擴充套件一個工廠類就可以。
3、遮蔽產品的具體實現,呼叫者只關心產品的介面。

缺點:每次增加一個產品時,都需要增加一個具體類和物件實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。
整合後的程式碼:

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

namespace 工廠方法模式
{
    class Program
    {
    //使用工廠方法
        static void Main(string[] args)
        {
            fact = new UniFactory();
            lei = fact.getvol();
            lei.cook();
            lei.sweep();
            lei.wash();
        }
    }
}
//抽象產品基類
abstract class Volunteer
{
    public abstract void sweep();
    public abstract void cook();
    public abstract void wash();
}
//具體產品子類
class Leifeng : Volunteer
{
    public override void sweep()
    {
        Console.WriteLine("雷鋒掃地");
    }
    public override void cook()
    {
        Console.WriteLine("雷鋒煮飯");
    }
    public override void wash()
    {
        Console.WriteLine("雷鋒洗衣");
    }
}
//抽象工廠類
abstract class Factory
{
    public abstract Volunteer getvol();
}
//具體工廠
class LeiFactory : Factory
{
    public override Volunteer getvol()
    {
        return (new Leifeng());
    }
}

      使用工廠方法實現的系統,如果系統需要新增新產品時,我們可以利用多型性來完成系統的擴充套件,對於抽象工廠類和具體工廠中的程式碼都不需要做任何改動。
      例如,我們我們增加一個人物:“博主”,此時我們只需要定義一個具體工廠——“博主”和具體產品——“博主”子類就可以。而不用像簡單工廠模式中那樣去修改工廠類中的實現(具體指新增case語句)。具體程式碼為:

//具體工廠——博主
class BloggerFactory : Factory
{
    public override Volunteer getvol()
    {
        return (new BloggerFactory ());
    }
}
//具體產品——博主子類
class Blogger: Volunteer
{
    public override void sweep()
    {
        Console.WriteLine("博主掃地");
    }
    public override void cook()
    {
        Console.WriteLine("博主煮飯");
    }
    public override void wash()
    {
        Console.WriteLine("博主洗衣");
    }
}

好了,工廠模式介紹完了,博主也該去掃地,煮飯,洗衣了。