設計模式——工廠模式(Factory Pattern)
工廠模式:
假如你是一家汽車公司的老闆,為了滿足世界各個國家的人的不同需要,在各個國家都建立了汽車生產工廠,每個工廠給該地區生產符合本地風格的汽車,那你的工廠和要生產的汽車是什麼樣的關係呢?讓我們用工廠模式通過Java來描述一下。
為了方便起見,現只在3個國家建立工廠ChinaFactory,EnglishFactory和JapanFactory,中國需要生產中國風的汽車ChineseCar,英國有英國式的汽車EnglishCar,日本有日式的汽車JapaneseCar。雖然汽車的風格各異,但是這些汽車都有一般汽車通用的屬性,如果另闢蹊徑建立各種怪異的汽車成本太高不說還不一定有市場,所以這三中汽車都有一個共同的父類Car。當然汽車工廠也是在CarFactory工廠的基礎之上改進而來。
據上所述,CarFactory與Car是其他汽車工廠與汽車的父類,這個工廠體系可以用父子類的方式構建,但是實際需要的是子類的例項,就是不同風格的汽車工廠與所生產的汽車,而不是父類的例項。CarFactory與Car更像是設計圖或者規則,為子類設定好工廠生產方式與汽車的模型,而具體的實現要到實際中根據各的風格來決定,所以這個工廠體系可以用介面與類的方式或者抽象類與子類的方式構建,由於這裡不需要用到成員變數就用介面與類的方式構建。
工廠模式的UML類圖
為什麼少了一個工廠呢?由於資金和國家批證等原因EnglishFactory沒有預期建成(呵呵,隨便找個理由)!等了好久終於所有的事情都弄好了,久終於可以在英國建工廠了。這時你會發現建立英國的工廠相當的容易,只需要用EnglishFactory與EnglishCar分別實現CarFactory和Car這兩個介面,並用EnglishFactory關聯EnglishCar就建立起你的工廠子類!
增加了EnglishFactory與EnglishCar的UML類圖
工廠模式程式碼:
public interface Car { public void printName(); } public class ChineseCar implements Car { public void printName() { System.out.println("ChineseCar"); } } public class EnglishCar implements Car { public void printName() { System.out.println("EnglishCar"); } } public class JapaneseCar implements Car { public void printName() { System.out.println("JapaneseCar"); } } public interface CarFactory { public Car getInstance(); } public class ChinaFactory implements CarFactory { public Car getCarInstance() { return new ChineseCar(); } } public class EnglishFactory implements CarFactory { public Car getCarInstance() { return new EnglishCar(); } } public class JapanFactory implements CarFactory { public Car getCarInstance() { return new JapaneseCar(); } }
Client測試類:
public class Client {
public static void main(String[] args) {
CarFactory cf ;
Car car ;
cf = new ChinaFactory();
car = cf.getCarInstance();
car.printName();
cf = new EnglishFactory();
car = cf.getCarInstance();
car.printName();
cf = new JapanFactory();
car = cf.getCarInstance();
car.printName();
}
}
執行結果:工廠模式的使用場景:
1、客戶端使用物件存在變動,或者不知道該建立什麼物件。
2、客戶端不用知道產品物件的建立過程
3、需要封裝建立類物件的邏輯,使得這些邏輯區域性化
工廠模式的優點/缺點:
優點:
1、增加新的產品很容易,只需實現產品介面和工廠介面
2、客戶端不用知道產品物件的建立過程
3、支援開閉原則
缺點:
1、沒有真正的避免修改原始碼,當增加新產品時要麼在客戶端將工廠寫死,要麼將判斷寫在抽象工廠。使用配置檔案可以解決這一問題。如spring
2、當產品越來越多時,工廠也會越來越多,出現類爆炸的情況。
3、只能產生某類產品,不能產生系列產品