工廠三兄弟之簡單工廠模式
模式定義:
簡單工廠模式(Simple Factory Pattern):定義一個工廠類,它可以根據參數的不同傳回不同類的 執行個體,被建立的執行個體通常都具有共同的父類。因為在簡單工廠模式中用于建立執行個體的方法是 靜态(static)方法,是以簡單工廠模式又被稱為靜态工廠方法(Static Factory Method)模式,它屬 于類建立型模式。
多讀幾遍定義 然後我們來看下它的結構:
簡單工廠模式的要點在于:當你需要什麼,隻需要傳入一個正确的參數,就可以擷取你所需 要的對象,而無須知道其建立細節。
來來來 舉個栗子:
Sunny軟體公司欲基于Java語言開發一套圖表庫,該圖表庫可以為應用系統提供各種不同外觀 的圖表,例如柱狀圖、餅狀圖、折線圖等。Sunny軟體公司圖表庫設計人員希望為應用系統開 發人員提供一套靈活易用的圖表庫,而且可以較為友善地對圖表庫進行擴充,以便能夠在将 來增加一些新類型的圖表。
然後程式員出了個設計方案,并将圖表的實作代碼封裝在Chart類中:
|
用戶端代碼通過調用Chart類的構造函數來建立圖表對象,根據參數type的不同可以得到不同 類型的圖表,然後再調用display()方法來顯示相應的圖表。
不難看出,Chart類是一個“巨大的”類,在該類的設計中存在如下幾個問題:
(1) 在Chart類中包含很多“if…else…”代碼塊,整個類的代碼相當冗長,代碼越長,閱讀難度、 維護難度和測試難度也越大;而且大量條件語句的存在還将影響系統的性能,程式在執行過 程中需要做大量的條件判斷。
(2) Chart類的職責過重,它負責初始化和顯示所有的圖表對象,将各種圖表對象的初始化代碼 和顯示代碼集中在一個類中實作,違反了“單一職責原則”,不利于類的重用和維護;而且将大 量的對象初始化代碼都寫在構造函數中将導緻構造函數非常龐大,對象在建立時需要進行條 件判斷,降低了對象建立的效率。
(3) 當需要增加新類型的圖表時,必須修改Chart類的源代碼,違反了“開閉原則”。
(4) 用戶端隻能通過new關鍵字來直接建立Chart對象,Chart類與用戶端類耦合度較高,對象的 建立和使用無法分離。
(5) 用戶端在建立Chart對象之前可能還需要進行大量初始化設定,例如設定柱狀圖的顔色、高 度等,如果在Chart類的構造函數中沒有提供一個預設設定,那就隻能由用戶端來完成初始設 置,這些代碼在每次建立Chart對象時都會出現,導緻代碼的重複。
面對這種如此巨大、職責如此重,且與用戶端代碼耦合度非常高的類,我們應該怎麼辦?
先上代碼 看看我們用簡單工廠模式改造後的效果:
|
現在的代碼結構:
是不是對強迫症很治愈!!!當我們需要切換執行個體時唯一的改動隻是用戶端的入參:
chart = ChartFactory.getChart("pie");
但是還是有改動,不符合開閉原則了,我要換圖表還是要改用戶端的代碼。這時候我們的解決辦法是将靜态工廠方法的參數存儲在properties中然後在程式中引用它:
String type = XMLUtil.getChartType(); //讀取配置檔案中的參數
chart = ChartFactory.getChart(type); //建立産品對象
至此簡單工廠模式的設計demo就講完了。
下面我們分析下這種模式:
簡單工廠模式的優點:
1.用戶端免除了建立産品對象的職責,僅僅是“消費“産品,實作了對象和使用的分離;
2.用戶端無需知道具體産品類的類名,隻需知道對應産品的對應入參,減少記憶量;
3.通過引入配置檔案可以不修改用戶端的情況下更換産品,提高靈活性;
缺點:
1.工廠類集中了所有産品的建立邏輯,職責過重;
2.式勢必會增加系統中類的個數,增加了系統的複雜 度和了解難度;
3. 系統擴充困難,一旦添加新産品就不得不修改工廠邏輯,在産品類型較多時,有可能造成 工廠邏輯過于複雜,不利于系統的擴充和維護。
4.由于使用了靜态工廠方法,造成工廠角色無法形成基于繼承的等級結構。
适用場景:
(1) 工廠類負責建立的對象比較少,由于建立的對象較少,不會造成工廠方法中的業務邏輯太 過複雜。
(2) 用戶端隻知道傳入工廠類的參數,對于如何建立對象并不關心。
來來思考下為啥靜态?
static方法可以通過類名通路,也可以通過類的執行個體通路。
static方法不能通路類中非static的資料。
比如
class A { static void F(){} };
在main函數中可以
A a;
a.F();
也可以 A.F();
普通方法又叫執行個體方法,隻能通過類的執行個體通路。
他隻能a.F();
一個JAVA類被加載的順序:
1.加載靜态成員、代碼塊
2.加載非靜态成員、代碼塊
3.調用構造方法。
其實不用靜态方法也可以,隻是用靜态方法之後,就不用初始化工廠而直接得到産品。