java 工廠設計模(mo)式
工廠模式:主要用來實例化有共同接口的類,工廠模式可以動態決定應該實例化那一個類。
工廠模式(shi)的(de)形態
工廠模式主要用一下幾種形態:
1:簡單工廠(Simple Factory)。
2:工廠方法(Factory Method)。
3:抽象工廠(Abstract Factory)。
簡單(dan)工廠(Simple Factory)
又叫靜態工廠,是工廠模式三中狀態中結構最為簡單的。主要有一個靜態方法,用來接受參數,并根據參數來決定返回實現同一接口的不同類的實例。我們來看一個具體的例子:
假設一家工廠,幾生產洗衣機,有生產冰箱,還有空調等等..
我們先為所有產品定義一個共同的產品接口
- public interface Product{}
接著我們讓這個工廠的所有產品都必須實現此接口
- public class Washer implements Product{
- public Washer(){
- System.out.println("洗衣機(ji)被(bei)制(zhi)造了");
- }
- }
- public class Icebox implements Product{
- public Icebox(){
- System.out.println("冰箱被制造了");
- }
- }
- public class AirCondition implements Product{
- public Icebox(){
- System.out.println("空(kong)調被制造了");
- }
- }
接下來我們來寫一個工廠類,有它來負責生產以上的產品
- public class SimpleFactory {
- public static Product factory(String productName) throws Exception{
- if(productName.equals("Washer")){
- return new Washer();
- }else if(productName.equals("Icebox")){
- return new Icebox();
- }else if(productName.equals("AirCondition")){
- return new AirCondition();
- }else{
- throw new Exception("沒有該產品(pin)");
- }
- }
- }
好了,有了這個工廠類,我們就可以開始下定單了,SimpleFactory將根據不同的定單類決定生產什么產品。
- public static void main(String[] args) {
- try {
- SimpleFactory.factory("Washer");
- SimpleFactory.factory("Icebox");
- SimpleFactory.factory("AirCondition");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
由上面的代碼可以看出,簡單工廠的核心就是一個SimpleFactory類,他擁有必要的邏輯判斷能力和所有產品的創建權利,我們只需要向把定單給他,就能得到我們想要的產品。這使用起來似乎非常方便。
但,實際上,這個SimpleFactory有很多的局限。首先,我們每次想要增加一種新產品的時候,都必須修改SimpleFactory的原代碼。其次,當我們擁有很多很多產品的時候,而且產品之間又存在復雜的層次關系的時候,這個類必須擁有復雜的邏輯判斷能力,其代碼量也將不斷地激增,這對以后的維護簡直就是恐怖兩個字...
還有就是,整個系統都嚴重依賴SimpleFactory類,只要SimpleFactory類一出問題,系統就進入不能工作的狀態,這也是最為致命的一點....
以上的不足將在工廠模式的另外兩種狀態中得到解決。
工(gong)廠(chang)方法(Factory Method)
上面的代碼告訴我們,簡單工廠并不簡單,它是整個模式的核心,一旦他出了問題,整個模式都將受影響而不能工作,為了降低風險和為日后的維護、擴展做準備,我們需要對它進行重構,引入工廠方(fang)法。
工廠方法為工廠類定義了接口,用多態來削弱了工廠類的職能,以下是工廠接口的定義:
- public interface Factory{
- public Product create();
- }
我們再來定義一個產品接口
- public interface Product{}
一下是實現了產品接口的產品類
- public class Washer implements Product{
- public Washer(){
- System.out.println("洗衣機被制造了");
- }
- }
- public class Icebox implements Product{
- public Icebox(){
- System.out.println("冰箱被制造了");
- }
- }
- public class AirCondition implements Product{
- public Icebox(){
- System.out.println("空(kong)調(diao)被制造了");
- }
- }
接下來,就是工廠方法的核心部分,也就是具體創建產品對象的具體工廠類,
- //創建洗(xi)衣(yi)機的工(gong)廠
- public class CreateWasher implements Factory{
- public Product create(){
- return new Washer();
- }
- }
- //創建冰箱的工廠
- public class CreateIcebox implements Factory{
- public Product create(){
- return new Icebox();
- }
- }
- //創建空調的工廠(chang)
- public class CreateAirCondition implements Factory{
- public Product create(){
- return new AirCondition();
- }
- }
從上面創建產品對象的代碼可以看出,工(gong)廠方法和簡單工廠的主要區別是,簡單(dan)工廠是把創建產品的職能都放在一個類里面,而工(gong)廠方(fang)法則把不同的產品放在實現了工廠接口的不同工廠類里面,這樣就算其中一個工廠類出了問題,其他工廠類也能正常工作,互相不受影響,以后增加新產品,也只需要新增一個實現工廠接口工廠類,就能達到,不用修改已有的代碼。但工廠(chang)方法(fa)也有他局限的地方,那就是當面對的產品有復雜的等級結構的時候,例如,工廠除了生產家電外產品,還生產手機產品,這樣一來家電是手機就是兩大產品家族了,這兩大家族下面包含了數量眾多的產品,每個產品又有多個型號,這樣就形成了一個復雜的產品樹了。如果用工(gong)廠方法來設計這個產品家族系統,就必須為每個型號的產品創建一個對應的工廠類,當有數百種甚至上千種產品的時候,也必須要有對應的上百成千個工廠類,這就出現了傳說的類爆炸,對于以后的維護來說,簡直就是一場災難.....
抽象工(gong)廠(chang)(Factory Method)
抽象(xiang)工廠:意的意圖在于創建一系列互相關聯或互相依賴的對象。<<Java設計模式>>
我自己覺得抽象工(gong)廠是在工(gong)廠方法的基礎上引進了分類管理的概念....
工廠方法用來創建一個產品,它沒有分類的概念,而抽象工廠則用于創建一系列產品,所以產品分類成了抽象工廠的重點,
我們繼續用上面的例子來說明:
工廠生產的所有產品都用都用大寫字母來標明它們的型號,比如冰箱,就有“冰箱-A",“冰箱-B",同樣,其他的產品也都是遵守這個編號規則,于是就有了一下產品家族樹
冰箱:
- 冰箱-A
- 冰箱-B
洗衣機:
- 洗衣機-A
- 洗衣機-B
我們可以為冰箱和洗衣機分別定義兩個產品接口,以對他們進行分類,
- //洗衣機接口
- public interface Washer{
- }
- //冰(bing)箱接口
- public interface Icebox{
- }
接著,我們分別創建這兩個接口的具體產品
- //洗衣機-A
- public class WasherA implements Washer{
- public WasherA(){
- System.out.println("洗衣機-A被制造了");
- }
- }
- //洗衣(yi)機-B
- public class WasherB implements Washer{
- public WasherB(){
- System.out.println("洗(xi)衣機-B被制造了");
- }
- }
- //冰箱-A
- public class IceboxA implements Icebox{
- public IceboxA(){
- System.out.println("冰箱-A被制造了(le)");
- }
- }
- //冰箱-B
- public class IceboxB implements Icebox{
- public IceboxB(){
- System.out.println("冰(bing)箱-B被制造了");
- }
- }
到此,產品部分我們準備好了,接下來我們來處理工廠部分,我們先來定義工廠行為接口
- public interface Factory{
- public Washer createWasher();
- public Icebox createIcebox();
- }
接下來我創造具體的工廠類,我們根據上面產品的接口,把型號A的產品分為一類,由一個工廠來管理,把型號為B的產品有另一個工廠管理,根據這個分類,我們可以實現如下的兩個具體工廠類
- //創建型號為A的產品工廠
- public class FactoryA implements Factory{
- //創建(jian)洗衣機-A
- public Washer createWasher(){
- return new WasherA();
- }
- //創建(jian)冰箱-A
- public Icebox createIcebox(){
- return new IceboxA();
- }
- }
- //創建型號為(wei)B的產品(pin)工廠
- public class FactoryB implements Factory{
- //創(chuang)建洗衣(yi)機-B
- public Washer createWasher(){
- return new WasherB();
- }
- //創建冰(bing)箱(xiang)-B
- public Icebox createIcebox(){
- return new IceboxB();
- }
- }
這樣,我們的(de)(de)抽(chou)象工(gong)(gong)(gong)(gong)廠(chang)(chang)就(jiu)完成了。有(you)(you)上(shang)(shang)面(mian)可以(yi)看(kan)出,在運用(yong)(yong)上(shang)(shang)我覺得工(gong)(gong)(gong)(gong)廠(chang)(chang)方法(fa)和抽(chou)象工(gong)(gong)(gong)(gong)廠(chang)(chang),都有(you)(you)自己(ji)的(de)(de)應用(yong)(yong)場(chang)景,并沒有(you)(you)什么優劣(lie)之分,但在應用(yong)(yong)抽(chou)象工(gong)(gong)(gong)(gong)廠(chang)(chang)之前,要先對創(chuang)建(jian)的(de)(de)對象進(jin)行系統(tong)的(de)(de)分類,這點很重要,好(hao)的(de)(de)產品(pin)分類規(gui)則(ze)能(neng)為具體工(gong)(gong)(gong)(gong)廠(chang)(chang)類的(de)(de)選擇調用(yong)(yong)和以(yi)后的(de)(de)擴(kuo)展提供清晰的(de)(de)思路(lu).
注: 本文引用自:

