天天看點

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

版權聲明:尊重部落客原創文章,轉載請注明出處哦~http://blog.csdn.net/eson_15/article/details/51223124

        工廠模式使用的頻率非常高,我們在開發中總能見到它們的身影。其定義為:define an interface for creating an object, but let subclasses decide which class to instantiate. factory method lets a class defer instantiation to subclasses.即定義一個用于建立對象的接口,讓子類決定執行個體化哪一個類。工廠方法使一個類的執行個體化延遲到其子類。工廠方法模式的通用類圖如下所示:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

        如圖所示,product抽象類負責定義産品的共性,實作對事物最抽象的定義,creator為抽象工廠類,具體如何建立産品類由具體的實作工廠concretecreator來完成。我們來看一下通用的模闆代碼:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public abstract class product {  

    public void method() { //産品類的公共方法,已經實作  

        //實作了公共的邏輯  

    }  

    public abstract void method2(); //非公共方法,需要子類具體實作  

}  

        具體産品類可以有多個,都繼承與抽象類product,如下:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class concreateproduct1 extends product {  

    @override  

    public void method2() {  

        //product1的業務邏輯  

public class concreateproduct2 extends product {  

        //product2的業務邏輯  

        抽象工廠類負責定義産品對象的産生,代碼如下:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public abstract class creator {  

    //建立一個産品對象,其輸入參數類型可以自行設定  

    public abstract <t extends product> t createproduct(class<t> clazz);  

       這裡用的是泛型,傳入的對象必須是product抽象類的實作類。具體如何産生一個産品的對象,是由具體工廠類實作的,具體工廠類繼承這個抽象工廠類:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class concretecreator extends creator {  

    public <t extends product> t createproduct(class<t> clazz) {  

        product product = null;  

        try {  

            product = (product) class.forname(clazz.getname()).newinstance();  

        } catch (exception e) { //異常處理  

            e.printstacktrace();  

        }  

        return (t) product;  

        通過這樣的設計,我們就可以在測試類中随意生産産品了,看下面的測試類:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class factorytest {  

    public static void main(string[] args) {  

        creator factory = new concretecreator();  

        product product1 = factory.createproduct(concreteproduct1.class); //通過不同的類建立不同的産品  

        product product2 = factory.createproduct(concreteproduct2.class);  

         /* 

          * 下面繼續其他業務處理 

          */  

     }  

        下面舉個女娲造人的例子闡述一下工廠模式的實際應用。

        現在女娲要造人,她要造三種人:白種人、黃種人和黑種人。怎麼造呢?她得有個能産生人類的工廠吧(類似于八卦爐的東西),這個工廠得讓她生産出不同的人種。每個人都有兩個屬性:皮膚顔色和說話。那現在我們開始設計女蝸造人的程式,首先我們看一下造人的類圖:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

        抽象接口human是人類,裡面有兩個方法,getcolor獲得皮膚顔色,talk交談。下面三個具體human的實作類,分别實作三個人種。根據工廠模式,應該有個抽象工廠,abstracthumanfactory就擔當了這個責任,裡面有個抽象方法createhuman,那humanfactory就是實作類了,實作抽象工廠裡的方法。下面我們看看具體實作:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public interface human {      

    public void getcolor();//人有不同的顔色      

    public void talk(); //人會說話  

        接下來對human接口的不同實作:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class blackhuman implements human {// 黑種人  

    public void getcolor() {  

        system.out.println("black");  

    public void talk() {  

        system.out.println("black man");  

public class human implements human {   //黃種人  

        system.out.println("yellow");  

        system.out.println("yellow man");  

public class whitehuman implements human {//白種人  

        system.out.println("white");  

        system.out.println("white man");  

        好了,人的模子搞好了,現在女娲要開始搭建八卦爐了,于是女娲開始畫八卦爐模型了:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public abstract class abstracthumanfactory{  

    public abstract <t extends human> t createhuman(class<t> clazz); //注意這裡t必須是human的實作類才行,因為要造human嘛  

        然後女娲開始具體實作這個八卦爐了……

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class humanfactory extends abstracthumanfactory {  

    public <t extends human> t createhuman(class<t> clazz) {  

        human human = null;  

            human = (product) class.forname(clazz.getname()).newinstance();  

            system.out.println("人種産生錯誤");  

        return (t) human;  

        好,現在人種也有了,八卦爐也有了,剩下的就是采集黃土,然後指令八卦爐開始生産了:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

        abstracthumanfactory bagualu = new hunmanfactory();  

        human blackman = bagualu.createhuman(blackhuman.class); //黑人誕生了  

        human yellowman = bagualu.createhuman(yellohuman.class); //黃人誕生了  

        human whiteman = bagualu.createhuman(whitehuman.class); //白人誕生了  

      }  

        女娲就是這麼把人造出來的……這就是工廠模式!

        我們還用上面女娲造人的例子說明,現在女娲在思考一個問題:我現在隻需要一個工廠就可以把人生産出來,我幹嘛要具體的工廠對象呢?我隻要使用靜态方法就好了。這樣一想,于是女娲就開始把abstracthumanfactory抽象類去掉了,隻保留了humanfactory類,同時把createhuman方法設定成了static類型,搞定!

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class humanfactory {  

    public static <t extends human> t createhuman(class<t> clazz) {  

        然後女娲造人的時候就不用new什麼八卦爐了,直接用humanfactory類調用就行了:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

human blackman = humanfactory.createhuman(blackhuman.class);  

        這就是靜态工廠模式,在實際項目中,根據需求可以設定成靜态工廠類,但是缺點是擴充比較困難,如果就一個工廠,不需要擴充,可以這麼設計,仍然是很常用的。

        我們還以女娲造人為例,後來女娲想了想,,這人不可能就說話吧,還得有不同的屬性殺的,如果在一個八卦爐裡造,除了new一個人外,還得對不同的人設定不同的屬性,這樣的話,八卦爐有點吃不消阿……又有點亂啊……但是她想到了一個法子,每個人種弄個八卦爐,不同的八卦爐專門生産不同的人種,這樣就結構清晰了,她在造人的時候自己選擇與哪個八卦爐相關聯就行了。示意圖如下:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

        這樣的話abstracthumanfactory抽象類我們就要改寫了:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public abstract class abstracthumanfactory {  

    public abstract human createhuman();  

        注意抽象方法中已經不需要再傳遞相關類的參數了,因為每個具體的工廠都已經非常明确自己的職責:建立自己負責的産品類對象。是以不同的工廠實作自己的createhuman方法即可:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class blackhumanfactory extends abstracthumanfactory {  

    public human createhuman() {  

        return new blackhuman();  

public class yellowhumanfactory extends abstracthumanfactory {  

        return new yellowhuman();  

public class whitehumanfactory extends abstracthumanfactory {  

        return new whitehuman();  

        這樣三個不同的工廠就産生了,每個工廠對應隻生産自己對應的人種。是以現在女娲造人就可以不用一個八卦爐了,分工協作,各不影響了!

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

        human blackman = new blackhumanfactory().createhuman(); //黑人誕生了  

        human yellowman = new yellowhumanfactory().createhuman(); //黃人誕生了  

        human whiteman = new whitehumanfactory().createhuman(); //白人誕生了  

        這種工廠模式的好處是職責清晰,結構簡單,但是給擴擴充性和可維護性帶來了一定的影響,因為如果要擴充一個産品類,就需要建立一個相應的工廠類,這樣就增加了擴充的難度。因為工廠類和産品類的數量是相同的,維護時也需要考慮兩個對象之間的關系。但是這種模式還是很常用的。

        上一章介紹了單例模式,并且指出了單例和多例的一些缺點,但是我們是不是可以采用工廠模式來實作一個單例模式的功能呢?答案是肯定的,單例模式的核心要求就是在記憶體中隻有一個對象,通過工廠方法模式也可以隻在記憶體中生産一個對象。見下面:

singleton類定義了一個private的無參構造方法,目的是不允許通過new的方式建立對象,另外,singleton類也不自己定義一個singleton對象了,因為它要通過工廠來獲得。

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class singleton {  

    private singleton() {  

    public void dosomething() {  

        //業務處理  

        既然singleton不能通過正常的管道建立一個對象,那singletonfactory如何建立一個單例對象呢?答案是通過反射方式建立:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class singletonfactory {  

    private static singleton instance;  

    static {  

        try {         

            class clazz = class.forname(singleton.class.getname());  

            //擷取無參構造方法  

            constructor constructor = clazz.getdeclaredconstructor();  

            //設定無參構造方法可通路  

            constructor.setaccessible(true);  

            //産生一個執行個體對象  

            instance = (singleton) constructor.newinstance();  

        } catch (exception e) {  

            //異常處理  

    public static singleton getinstance() {  

        return instance;  

        以上通過工廠方法模式建立了一個單例對象,該架構可以繼續擴充,在一個項目中可以産生一個單例構造器,所有需要産生單例的類都遵循一定的規則(構造方法是private),然後通過擴充該架構,隻要輸入一個類型就可以獲得唯一的一個執行個體。

        何為延遲初始化(lazy initialization)?即一個對象被使用完畢後,并不立刻釋放,工廠類保持其初始狀态,等待再次被使用。延遲初始化是工廠模式的一個擴充應用,其通用類表示如下:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

        productfactory負責産品類對象的建立工作,并且通過prmap變量産生一個緩存,對需要再次被重用的對象保留:

【java設計模式】之 工廠(Factory)模式 1.工廠模式的定義 2.用女蝸造人闡述工廠模式 3.工廠模式的擴充 4. 工廠模式的應用

public class productfactory {  

    private static final map<string, product> prmap = new hashmap();  

    public static synchronized product createproduct(string type) throws exception {  

        //如果map中已經有這個對象  

        if(prmap.containskey(type)) {  

            product = prmap.get(type);  

        } else {  

            if(type.equals("product1")) {  

                product = new concreteproduct1();  

            }  

            else {  

                product = new concreteproduct2();  

            prmap.put(type, product);  

        return product;  

        代碼比較簡單,通過定義一個map容器,容納所有産生的對象,每次在new一個對象的時候先判斷map中有沒有,有就不用再new了,直接取。另外,每次new過一個對象後,也将其放入map中友善下次調用。

    優點:

        1. 工廠模式具有良好的封裝性,代碼結構清晰,也有利于擴充。在增加産品類的情況下,隻需要适當地修改具體的工廠類或擴充一個工廠類,就可以完成“擁抱變化”。

        2. 工廠模式可以屏蔽産品類。這一點非常重要,産品類的實作如何變化,調用者都不用關系,隻需要關心産品的接口,隻要接口保持不變,系統的上層子產品就不需要發生變化。

        3. 工廠模式是典型的解耦架構。高層子產品隻需要知道産品的抽象類,其他的實作類都不用關心。

       工廠模式就介紹這麼多吧,如果錯誤之處,歡迎留言指正~

_____________________________________________________________________________________________________________________________________________________

-----樂于分享,共同進步!