Java設計模式:原廠模式

來源:互聯網
上載者:User

標籤:interface   public   現實生活   關鍵點   小汽車   

問題提出

Java的原廠模式與現實生活中的工廠的模型是很相似的。工廠是用來做什嗎?當然是用來產生產品。因此在Java的原廠模式的關鍵點就是如何描述好產品和工廠這2個角色之間的關係。

 

下面來仔細描述一下不同的關係以及對應的設計模式

1)單一產品系,工廠只生產一種類型的產品

650) this.width=650;" src="http://images2015.cnblogs.com/blog/1055141/201704/1055141-20170417224329212-1678195478.png" style="border:none;height:auto;" />

讓我們簡單構思一下簡單的工廠生產模型,既然只有一個產品,那隻需要一個車間就好了,一個車間分別生產三種不同種類的小汽車。好,下面看看簡單工廠的設計模式。

650) this.width=650;" src="http://images2015.cnblogs.com/blog/1055141/201704/1055141-20170417224355899-859322894.png" style="border:none;height:auto;" />

//定義小汽車介面:ICar.javapublic interface ICar {}
public class TopCar implements ICar {}
public class MidCar implements ICar {}
public class LowCar implements ICar {}

650) this.width=650;" src="/img/fz.gif" alt="複製代碼" style="border:none;" />

public class CarSimpleFactory {    public static final String TOPTYPE = "toptype";    public static final String MIDTYPE = "midtype";    public static final String LOWTYPE = "lowtype";    private CarSimpleFactory(){            }    public static ICar create(String mark){        ICar obj = null;        if(mark.equals(TOPTYPE)){            obj = new TopCar();        }        else if(mark.equals(MIDTYPE)){            obj = new MidCar();        }        else if(mark.equals(LOWTYPE)){            obj = new LowCar();        }        return obj;    }}

650) this.width=650;" src="/img/fz.gif" alt="複製代碼" style="border:none;" />

簡單工廠功能類編寫步驟:

1.編寫抽象產品介面

2.編寫具體產品子類

3.編寫工廠類。簡單工廠類的特點,它是一個具體的類,非介面型抽象類別。有一個重要的create()方法,並且用if...else或者switch開發建立所需產品。因為可以把這個簡單工廠類實現成一個工具類,所以直接用靜態方法就可以了,如有必要甚至可以把構造方法私人化。

 

下面考慮一種情形,工廠擴張啦!可以加工生產超級高檔型的汽車。在上面的生產模式下要怎麼修改呢?

1)新增ICar子類SuperCar

2)修改工廠類SimpleCarFactory中的create()方法,添加判斷分支。

子類SuperCar的添加是必然的,然而能不能不用修改工廠類呢?

或者從另一個角度分析,在一個生產線上生產幾種不同種類的產品,這樣我們還需要對每個產品加以判斷種類來分類。當然,假若只有2種種類要區分,這樣當然沒問題,但是若是有多個種類要區分呢?顯然,不能在一條生產線上生產多種種類的產品!那意味著對於每一種種類我們都需要一條生產線。這就是所謂的原廠模式!

650) this.width=650;" src="http://images2015.cnblogs.com/blog/1055141/201704/1055141-20170417224658774-173264373.png" style="border:none;height:auto;" />

public abstract class AbstractFactory {    public abstract ICar create();}

650) this.width=650;" id="code_img_closed_fa8cb3de-907c-4613-851e-c050533cd21b" src="/img/jia.gif" style="border:none;" /> View Code

650) this.width=650;" id="code_img_closed_13ea3324-b342-48fb-82c4-ee164edefe08" src="/img/jia.gif" style="border:none;" /> View Code

650) this.width=650;" id="code_img_closed_48ca85fa-0cc4-40af-aa9a-e3cb0aff88f9" src="/img/jia.gif" style="border:none;" /> View Code

而觀察代碼,只要有ICar.java,AbstractFactory.java這兩個檔案,其他具體產品類,工廠類源檔案沒有,編譯也能通過。

對於AbstractFactory,可以定義為抽象類別,也可以定義為介面。這裡的create()是抽象方法,沒參數,表明在具體的子類工廠中建立某個具體產品。

Factory 方法的主要特徵是:當需求分析發生變化是,只需要增加和刪除相應的類,而不是修改已有的類。例如添加超高檔的小汽車,只需要增加SuperCar以及SuperFactory兩個類即可。所以Factory 方法更易於軟體的二次開發以及維護。

當然啦,一個工廠很有可能不止產生一種產品。下面看看多產品系。

2)多產品系,特徵相同

650) this.width=650;" src="http://images2015.cnblogs.com/blog/1055141/201704/1055141-20170417224919259-1811132204.png" style="border:none;height:auto;" />

UML圖與原廠模式基本沒什麼區別,這裡就不再畫了。

一般來說,簡單工廠和原廠模式都是單產品系的,而對於上面這種架構,稱之為抽象工廠。但從本質上來說,抽象工廠和原廠模式是統一的。這裡就不再述說。

3)多產品系,部分特徵相同

650) this.width=650;" src="http://images2015.cnblogs.com/blog/1055141/201704/1055141-20170417225003790-666615638.png" style="border:none;height:auto;" />

public abstract class AbstractFactory {    /**     * 多產品系,小汽車和公用汽車都有高,中檔類型,小汽車有低檔類型,而公用汽車沒有     */}
public abstract class AbstractFactory1 extends AbstractFactory {    public abstract ICar createCar();   //產生小汽車對象    public abstract IBus createBus();   //產生公用汽車對象}
public abstract class AbstractFactory2 extends AbstractFactory {    public abstract ICar createCar(); //產生小汽車對象}

這裡著重看看AbstractFactory,AbstractFactory1,AbstractFactory2.

1)具有相同特徵的小汽車和公用汽車放在相同的工廠裡面

2)該類也是抽象類別,表明“特徵是多個”。這裡特徵表示“高中低檔”。

 

原廠模式大概就講到這裡,看到這裡,相信很多人都有一種,原廠模式原來也不過如此。但是,個人覺得無論什麼設計模式,看上去都似乎很好理解很容易。但是,當遇到問題需要自己分析設計的時候,就頓時沒了頭緒。

原因大概有2個,一是對這種設計模式還並不是十分熟悉和理解,二當然就是沒有實踐過。閑話不多說,下面讓我們操刀實踐一波。

 

 

例子:編寫讀檔案功能。讀取文字檔,包括GBK,UTF-8.編碼下的文字檔,要求獲得全文內容;讀取影像檔,包括BMP,GIF,JPG檔案,要求獲得映像寬度,長度,每一點的三基色資訊。

650) this.width=650;" src="http://images2015.cnblogs.com/blog/1055141/201704/1055141-20170417225217634-1489298231.png" style="border:none;height:auto;" />

代碼如下:

讀取文字檔方法需要兩個參數:檔案名稱和編碼方式;而讀取影像檔需要一個參數:檔案名稱。而根據題意,兩種讀取檔案傳回值類型有所差異。

如何用介面屏蔽方法參數個數,傳回值類型的差異,是定義介面的關鍵。

public interface IRead<T> {    //如何用介面屏蔽方法參數個數,傳回值類型的差異,這是定義介面的關鍵    T read(String ... in);}

650) this.width=650;" id="code_img_closed_a76a8422-8160-47d3-a900-92106d565f96" src="/img/jia.gif" style="border:none;" /> View Code

650) this.width=650;" id="code_img_closed_c2b4136f-1920-4bc6-a341-4a53bdbb8eba" src="/img/jia.gif" style="border:none;" /> View Code

650) this.width=650;" id="code_img_closed_2e68c5a9-6674-4c58-a738-f29ed525130a" src="/img/jia.gif" style="border:none;" /> View Code

public abstract class AbstractFactory {  //定義抽象工廠    public abstract IRead create();}
public class TextFactory extends AbstractFactory {    public IRead create(){        return new TextRead();    }}
public class ImageFactory extends AbstractFactory {    public IRead create(){        return new ImageRead();    }}

對於上面抽象工廠類其實並不夠完善,如何選擇具體工廠類沒有體現。解決方案有兩種。一是像簡單工廠那樣添加選擇分支。二是使用反射。

下面的代碼是使用了反射技術

650) this.width=650;" src="/img/fz.gif" alt="複製代碼" style="border:none;" />

public abstract class AbstractFactory {    public abstract IRead create();    static AbstractFactory create(String className){        AbstractFactory factory = null;        try{            Class c = Class.forName(className);            factory = (AbstractFactory)c.newInstance();        }        catch (Exception ex){            ex.printStackTrace();        }        return factory;    }}

650) this.width=650;" src="/img/fz.gif" alt="複製代碼" style="border:none;" />

運用反射技術,實現了更加靈活的自動工廠選擇功能。當添加新具體工廠類的時候,不需要修改AbstractFactory類。


Java設計模式:原廠模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.