設計模式--------工廠模式

設計模式

設計模式--------工廠模式html

設計模式--------設計原則設計模式

前言

  兩個月前寫過一次設計模式系列,但很不滿意就刪除了。顯然但願能作到學以至用,而非看書總結,設計模式絕對是你解決問題的一個思路,但在這有點本身的小建議,設計模式ide

並非用做提升你代碼的效率,用它的目的只是讓你的代碼看起來更規範,更易擴展與維護。因此有的時候你站在你自身須要去選擇要不要使用設計模式。上週工做當中有一個需求ui

正好是適合用工廠模式來解決的,因此就在這給你們討論討論工廠模式吧。this

1.簡單工廠模式

  在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用一個共同的接口來指向新建立的對象。spa

好比說,我要給其餘終端提供保存實例的接口,可是實例卻用不少個,這時提供的接口,若是每一個實例都提供一邊,就會變成這樣提供多個端口,若是要增長就要繼續提供接口,故設計

此我就想到了用工廠模式。code

1.1.簡介:

  就比如中午你下樓去吃飯,別人問你幹啥去?你說我去吃黃燜雞,我去吃燴麪,我去吃肯德基,去吃麻辣燙。。。。這些好像沒錯,可是估計你不會這麼回答,你通常都是回答orm

我去吃飯。這就是工廠模式要走的,具體你要吃什麼東西,不用告訴別人,別人問的主題是你去幹什麼,你告訴他你娶吃飯就行,具體你要吃什麼,是你本身的決定,無需說出來。htm

  優勢: 一、一個調用者想建立一個對象,只要知道其名稱就能夠了。

      二、擴展性高,若是想增長一個產品,只要擴展一個工廠類就能夠。

     三、屏蔽產品的具體實現,調用者只關心產品的接口。

  缺點:每次增長一個產品時,都須要增長一個具體類和對象實現工廠,使得系統中類的個數成倍增長,在必定程度上增長了系統的複雜度,同時也增長了系統具體類的依賴。這

並非什麼好事。

1.2.實現(注:如下代碼均爲不帶邏輯的實例代碼)

組成部分:

工廠類角色:這是本模式的核心,在此它會根據不一樣的產品選擇生產什麼東西。

抽象產品角色:它通常是具體產品繼承的父類或者實現的接口。由接口或者抽象類來實現。

具體產品角色:工廠類所建立的對象就是此角色的實例。

首先定義一個接口(抽象產品角色):

public interface ISaveACDb
    {
        void SaveACDB();
    }

根據產品定義各自的類(具體產品類)

  public class SaveACDDbToBuChong : ISaveACDb
    {
        public bool SaveACDB()
        {
            return true;
        }
    }
    public class SaveACDDbToArchivesCases : ISaveACDb
    {
        public bool SaveACDB()
        {
            return true;
        }
    }

接口工廠類的定義:

  public class SaveACDb_Factory
    {
        public static ISaveACDb Create_SaveACDb_Factory(string type)
        {
            ISaveACDb save = null;
            switch (type)
            {
                case "ArchivesCases":
                    save = new SaveACDDbToArchivesCases();
                    break;
                case "BuChong":
                    save = new SaveACDDbToBuChong();
                    break;
            }
            return save;
        }
    }

調用代碼:

 public class WinformClientDbController : Controller
    {
        [HttpPost]
        public void SaveACInfo(string type)
        {
            var result = SaveACDb_Factory.Create_SaveACDb_Factory(type);
            result.SaveACDB();
        }
    }

問:若是一直增長產品,是否是就要增長產品類?

答:是的。

有沒有發現問題,這樣不斷增長產品,而後增長產品類到時沒什麼,可是相應的回去修改工廠類,有沒有發現,那麼這樣就有問題,就像我上篇設計模式提到的「開閉原則」,咱們在

這種模式下就充分的違背了,因此若是產品類若是會大量增長的話,你最起碼要知道這是違背設計原則的。

問:那該怎麼解決呢?

答:用反射。

2.簡單工廠與反射

  反設我已經在基礎拾遺------反射詳解介紹過來。

簡單工廠中使用反射的目的就是去掉工廠類中的switch(或if)。ps:想想這一改變,特別是我如今這種給其餘客戶端提供接口的程序,大大第提升代碼的解耦。

代碼以下:

  public class SaveACDb_Factory
    {
        public static ISaveACDb Create_SaveACDb_Factory(string obj, string className)
        {
            Assembly assembly = Assembly.GetExecutingAssembly(); // 獲取當前程序集
            var result = (ISaveACDb)assembly.CreateInstance("StrokeLocalWinformInterface" + ".SaveACDDbTo" + className);
            return result;
        }
    }

調用

        [HttpPost]
        public void SaveACInfo(string obj, string userNickeName, string userToken, string className)
        {
            if (1 > 2)//驗證usertoken
                return;
            var result = SaveACDb_Factory.Create_SaveACDb_Factory(obj, className);
            result.SaveACDB(obj);
        }

 

3.抽象工廠

  就像上面說的,若是咱們的產品不斷增長且成樹裝結構增長,咱們就要說說抽象工廠。

3.1.簡介:

  若是別人爲你幹啥去,你說你去吃飯去,可是你再去的過程中,若是考慮肯德基要吃雞翅仍是漢堡,他們都是什麼口味,去吃快餐都是有什麼。。。。這樣若是選擇一次吃

飯,是否是要想半個小時,因此去吃燴麪這個產品也能夠把它看成吃飯這個超級工廠的子工廠。

  抽象工廠就是圍繞這超級工廠創建的其餘工廠。超級工廠是其餘工廠的工廠。

  優勢:當一個產品族中的多個對象被設計成一塊兒工做時,它能保證客戶端始終只使用同一個產品族中的對象。

  缺點:產品族擴展很是困難,要增長一個系列的某一產品,既要在抽象的 Creator 里加代碼,又要在具體的裏面加代碼。

3.2.實現:

  抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。

  具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以建立對應的具體產品的對象。

  抽象產品角色:它是具體產品繼承的父類或者是實現的接口。

  具體產品角色:具體工廠角色所建立的對象就是此角色的實例。

  如下案例爲借鑑過來的,就是公司老闆有不少車,司機開車是一個超級工廠,每輛車是具體操做是另一個工廠,此次偷個懶就不本身寫案例啦。

抽象產品:就是定一個車的類,此類有一個司機開車的方法抽象方法,和具體是什麼車,進行賦值的方法。

 abstract class Car{ private String name; public abstract void drive(); public String getName() { return name; } public void setName(String name) { this.name = name; } } 

public interface Fruit
{
}
public interface Veggie
{

具體產品:繼承抽象產品,寶馬和奔馳都是不一樣的車。

 class Benz :Car{ public void drive(){ // } } class Bmw :Car{ public void drive(){ 
//
} }

public class NorthernFruit implements Fruit
{
private String name;
public NorthernFruit(String name)
{
}
public String getName()
{
return name;
}
public void setName(String name)
{
this. name = name;
}
}
public class TropicalFruit implements Fruit
{
private String name;
public TropicalFruit(String name)
{
}
public String getName()
{
return name;
}
public void setName(String name)
{
this. name = name;
}
}
public class NorthernVeggie implements Veggie
{
private String name;
public NorthernVeggie(String name)
{
}
public String getName()
{
return name;
}
public void setName(String name)
{
this. name = name;
}
}
public class TropicalVeggie implements Veggie
{
private String name;
public TropicalVeggie(String name)
{
}
public String getName()
{
return name;
}
public void setName(String name)
{
this. name = name;
}

抽象工廠:司機就是要開車嗎。這個工廠抽象司機開車。

abstract class Driver{ public abstract Car createCar(String car) throws Exception; } 
public interface Gardener
{
public Fruit createFruit(String name);
public Veggie createVeggie(String name);

具體工廠:開寶馬和奔馳仍是不同的,這個工廠針對不一樣的車去實例。

    class BenzDriver :Driver{ public Car createCar(String car) throws Exception { return new Benz(); } } class BmwDriver :Driver{ public Car createCar(String car) throws Exception { return new Bmw(); } } 
public class NorthernGardener implements Gardener
{
public Fruit createFruit(String name)
{
return new NorthernFruit(name);
}
public Veggie createVeggie(String name)
{
return new NorthernVeggie(name);
}
}
public class TropicalGardener implements Gardener
{
public Fruit createFruit(String name)
{
return new TropicalFruit(name);
}
public Veggie createVeggie(String name)
{
return new TropicalVeggie(name);
}
}

以上就是抽象工廠的組成部分,客戶端只需在實例化相應的工廠調用便可。

調用代碼:

//老闆  
    public class Boss{  
        public static void main(String[] args) throws Exception {  
            Driver d = new BenzDriver();  
            Car c = d.createCar("benz");   
            c.setName("benz");  
            c.drive();  
        }  
    }
相關文章
相關標籤/搜索