標籤:
簡單工廠、Factory 方法和抽象工廠都屬於設計模式建立型,嚴格意義上簡單工廠不屬於23設計模式之一(違背了開閉原則),本文為了完整描述三工廠演變過程,對三工廠進行了整體的總結和學習,並通過三者之間的特點比較總結出各自的優缺點。
一、簡單工廠:
在沒有工廠之前,大家都是自給自足,生產一部車或其他工具都是自己來完成,有了工廠之後,告訴它需求就會出來相應的產品,但生產化水平比較低,工廠分工不太明確,社會上只有一個工廠,不論卡車還是公交車都由它來完成,相當於一個工廠多條生產線。
類圖:
代碼:
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 簡單工廠類,用於生產各種汽車 * 開發時間:2015/8/20 16:05:29 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SimpleFactory{ class CarFactory { public static Car CreateCar(string type) { Car car = null; switch (type) { case "bus": car=new Bus (); break ; case "truck": car=new Truck (); break ; } return car; } }}
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 車的抽象類別,下面有公交車、卡車等,有生產車的虛方法 * 開發時間:2015/8/20 16:06:03 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SimpleFactory{ public class Car { public virtual void GetCar() { } }}
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 車的具體類之一,公交車 * 開發時間:2015/8/20 16:06:39 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SimpleFactory{ public class Bus:Car { public override void GetCar() { Console.WriteLine("生產出公交車!"); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SimpleFactory{ class Client { static void Main(string[] args) { Car car; car = CarFactory.CreateCar("bus");//需要生產公交車 car.GetCar(); } }}
好處:工廠類包含邏輯判斷,根據用戶端執行個體化相關類,去除與具體產品依賴,用戶端不管哪個類的執行個體,把需求給工廠,工廠單獨建立相應執行個體。是優點也是不足。
不足:如果添加產品,需要修改工廠類,違背開閉原則。Factory 方法的出現解決了這一困惑。。。
二、Factory 方法:
隨著專業化程度的提高,工廠分工變得明確,每個工廠生產各自的產品,公交車工廠只管生產公交車,卡車工廠負責生產卡車,這樣如果有新的產品需求,直接增加相應的產品類和對應 工廠類即可。
類圖:
代碼:和簡單工廠不同的是,多了一個抽象工廠介面,具體工廠類都來實現它。用戶端也來執行個體化具體工廠類(聲明時候是父類)。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ interface IFactory { Car CreateCar(); }}
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 公交車工廠 * 開發時間:2015/8/20 16:25:07 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ class BusFactory:IFactory { public Car CreateCar() { return new Bus(); } }}
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 用戶端,比如需要一輛公交車 * 開發時間:2015/8/20 16:06:39 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ class Client { static void Main(string[] args) { IFactory factory = new BusFactory();//執行個體化公交車工廠 Car car = factory.CreateCar(); //公交車工廠建立出公交車 car.GetCar(); } }}
好處:遵守開閉原則,直接添加具體產品類和相應工廠類,執行個體化哪一個工廠放在用戶端
不足:第一:增加一個產品就要增加一個產品工廠類,額外開發,第二:把簡單工廠內部邏輯移到用戶端,所以之前修改工廠類,現在修改用戶端,問題還是存在,抽象工廠的出現了。。。
三、抽象工廠:
Factory 方法雖解決簡單工廠違背開閉原則的問題,但它每個工廠只能生產一種產品,對於系列產品表示無能為力,而且大家都看到工廠能獲益,隨著工廠的增多,使用者的需求,這時有了品牌的概念,比如想要寶馬的卡車,平治的公交車等。。。
類圖:
代碼:
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 車的抽象類別,下面有公交車、卡車等,有生產車的虛方法 * 開發時間:2015/8/20 16:06:03 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ public class Bus { public virtual void GetCar() { } }}
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 車的具體類之一,平治公交車 * 開發時間:2015/8/20 16:06:39 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ public class BenzBus : Bus { public override void GetCar() { Console.WriteLine("生產出平治公交車!"); } }}
********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 平治工廠,生產平治公交和平治卡車 * 開發時間:2015/8/20 16:25:07 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ public class BenzFactory : IFactory { public Bus CreateBus() //生產平治公交 { return new BenzBus(); } public Truck CreateTruck()//生產平治卡車 { return new BenzTruck(); } }}
/********************************************************************************** * 開發人:李立平 * 開發組: * 類說明: 用戶端,需要平治公交和寶馬卡車 * 開發時間:2015/8/20 16:06:39 * 開發版本:V4.0.0 **********************************************************************************/using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AbstractFactory{ class Client { static void Main(string[] args) { Bus bb = new BenzBus();//聲明為父類 IFactory bf = new BenzFactory(); //建立平治工廠 bb = bf.CreateBus(); //生產平治公交 bb.GetCar(); Truck bt = new BMWTruck();//聲明為父類 IFactory tf = new BMWFactory();//建立寶馬工廠 bt = tf.CreateTruck();//生產寶馬卡車 bt.GetCar(); } }}
好處:可以解決Factory 方法每個工廠只能生產單一產品的工廠,根據產品需求進一步抽象出一個工廠類的抽象類別,所以為抽象工廠。通過改變具體工廠使用不同產品配置,第二:具體建立執行個體過程與用戶端分離,用戶端通過抽象介面操縱執行個體,
不足:增加新產品,比如福士的轎車,就要添加轎車抽象類別,和下面的福士轎車,福士卡車等,還有修改抽象工廠,和具體的工廠,比如就要添加福士的具體工廠,要修改的地方太多啦,這時就顯得糟糕了,不過可以通過簡單工廠改進抽象工廠。
抽象工廠的改進(更換資料庫的問題):
簡單工廠改進抽象工廠:一個database類,可以建立iuser和idepartment的sql和access產品,如果需要更換oracle資料庫呢?又需要在database中修改case分支,添加oracle資料庫的分支判斷,違背開閉原則,不好維護,這時把資料庫作為字串拿出來,反射出場了。
反射+抽象工廠:assembly.load(程式集).createinstance(命名空間.要執行個體化類名稱),原來寫死在程式裡,現在字串來是執行個體化對象(變數可以更換),資料庫使用由db決定,去除database中switch判斷,不過還需要改程式中db的值,不完美,有沒有一種不修改程式的方法,當然可以讀取設定檔啊。
設定檔+反射:真正符合開閉原則,讀檔案時給DB字串賦值,寫明用sql還是access,這樣database也不用更改啦。
四、比較:
比較:簡單工廠:生產同一等級任何產品,一個工廠多生產線;對增加新產品無能 為力;
Factory 方法:同一等級結構固定產品,多個工廠;
抽象工廠:生產不同系列的全部產品,對增加新產品無能為力。
每種模式都有自己的優點和弊端,只有最適合它的情境,沒有最好的時候,只要滿足自己的需求就是最好的。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
簡單工廠、Factory 方法與抽象工廠大比拼