常用的設計模式之工廠模式

寫在前面的話:

   雖然在我們的日常開發過程中,不用設計模式也可以完成相應的功能,但是用好的設計模式可以幫助我們更好的解決實際問題,設計模式一個重要的思想是解耦,降低代碼間的粘着性。幾乎我們所有的java框架和源碼都使用了良好的設計模式,比如spring就使用了諸如BeanFactory的工廠模式,mybatis框架的模板模式等等。學習設計模式可以更好的讓我們把業務轉化成技術實現。

   工廠模式從名字上來看,脫離於現實生活中的工廠,就是生成和製造各種產品的,比如口罩工廠。在Java的世界裏,工廠模式,也是同樣的道理,也是用來生產東西的(類實例對象)。在沒有該模式的情況下,我們一般生產對象(創建對象)一般都是採用new的形式。那爲什麼有了new的方式,還要提出一種“工廠模式”呢?原因其實還是比較容易理解,就比如這個生產口罩的工廠內部,口罩分多鐘型號,KN94/KN95/KF94等等。假如一個公民想要買口罩,我得告訴工廠我要哪種型號的吧,然後它生產出來給我。但生產某種型號的過程我是不知道的,不知道用了什麼材料,不知道用了什麼工藝對吧? 然後反過來想new的這種方式,一般代碼爲KouZhao kouZhao = new KouZhao(),使用new 的前提是什麼?得先知道KouZhao這個類吧,也就是說我得知道KouZhao是要用什麼材料用什麼工藝來做的,工廠模式就是 將這個過程隱藏起來只給結果給調用方。

1.簡單工廠模式

  簡單工廠就是我給你型號,你幫我生產,隱藏生產過程。new是我自己知道這個型號的製作過程和原理,自己申明生產過程。就 是傳入一個型號名稱(形參),內部if-else去判斷生產對象型號名稱的口罩。如果要新增型號,只能修改該工廠內部的if-else語句,新增判斷。

    KouZhaoFactory factory = new KouZhaoFactory();
    KN94KouZhao kn94 = (KN94KouZhao) factory.create("KN94");
    KN95KouZhao kn95 = (KN95KouZhao) factory.create("KN95");
    KF94KouZhao kf94 = (KF94KouZhao) factory.create("KF94");
    kn94.protect();
    kn95.protect();
    kf94.protect();

爲了避免字符串寫錯造成的問題可以使用反射改進一下:

 

KouZhaoFactory代碼如下:
 KouZhao create(Class <? extends  KouZhao> clazz){
       try {
         if (clazz!=null) {
            return clazz.newInstance();
         }
       } catch (Exception e) {
         e.printStackTrace();
       }
       return  null;
    }

 測試方法如下:

    KouZhaoFactory factory = new KouZhaoFactory();
    KN94KouZhao kn94 =(KN94KouZhao) factory.create(KN94KouZhao.class);
    KN95KouZhao kn95 =(KN95KouZhao) factory.create(KN95KouZhao.class);
    KF94KouZhao kf94 =(KF94KouZhao) factory.create(KF94KouZhao.class);
    kn94.protect();
    kn95.protect();
    kf94.protect();

從上面可以看出簡單工廠模式中工廠類的職責相對過重,所有的判斷和創建都在內部完成,不易於擴展過於複雜的產品結構。

2.工廠方法模式

    簡單工廠模式看起來像一個萬能工廠啥型號的口罩都可生成,工廠類的職責過重了,工廠方法模式是對簡單工廠進行了升級,不在由工廠類生成具體的口罩了,而是產生一個抽象的口罩接口,我們先創建一個口罩接口,再創建KN94、KN95、KF94實現類實現口罩接口。在使用時,直接給工廠傳入指定的實現類,內部利用反射的機制,綁定創建好指定型號(類型)的口罩。類圖如下:

測試代碼:

 

    KouZhaoFactory factory = new KN94KouZhaoFactory();
    KouZhao kn94 = factory.create();
    kn94.protect();

    KouZhaoFactory factory2 = new KN95KouZhaoFactory();
    KouZhao kn95 = factory2.create();
    kn95.protect();

    KouZhaoFactory factory3 = new KF94KouZhaoFactory();
    KouZhao kf94 = factory3.create();
    kf94.protect();

從上面可以看出工廠方法模式中類的過多比簡單工廠模式幾乎多了1倍,系統的複雜度也隨之增加,理解起來不是那麼容易。

3.抽象工廠模式

現實中一個工廠很少只生成1中產品的,通常情況都是如下圖所示:

我們將1個工廠相同顏色的各種產品稱作1個產品族,不同工廠的相同產品稱作1個產品等級結構,即上圖中的x軸和y軸。

在我們java世界裏抽象工廠模式源於此, 抽象工廠模式是工廠方法的升級。假設現在用戶想要購買口罩了,突然又想買點繃帶備用,如果沒有這個產品就很尷尬了,使用抽象工廠可以給用戶更多的選擇。類圖如下:

測試代碼:

    KouZhaoFactory factory = new KN94KouZhaoFactory();
    factory.createBengDai().blood();
    factory.createHuMuJing().protectEyes();
    factory.createKouZhao().protect();


    KouZhaoFactory factory2 = new KN95KouZhaoFactory();
    factory2.createBengDai().blood();
    factory2.createHuMuJing().protectEyes();
    factory2.createKouZhao().protect();

    KouZhaoFactory factory3 = new KF94KouZhaoFactory();
    factory3.createBengDai().blood();
    factory3.createHuMuJing().protectEyes();
    factory3.createKouZhao().protect();

總結:抽象工廠模式可以完美的展現出產品族和產品等級的關係,適用於產品數量不多的情況,過多的產品會使系統複雜度成倍遞增。

 

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章