簡單工廠模式(如下統一簡稱「工廠模式」)是一種建立型模式,因此是被用來建立對象的,也是最常使用的一種設計模式。它爲建立各類複雜的大對象提供了簡便的方式。在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而是經過使用一個統一的出口來建立的對象。java
聯想:生活中的工廠,工廠裏有不少流水線,能夠生產不一樣的產品,而一個工廠和這些產品必定是屬於同一個類型的。好比汽車工廠生產的是各類汽車,它確定不會生產食品,甚至是汽車零件!汽車的零件是由零件加工工廠生產的,汽車工廠只負責裝配。而對買方來講,買房只須要告訴工廠須要什麼,工廠自會爲其生產,而不須要知道生產的細節。數據庫
開發過程當中老是伴隨着建立大量的對象,當有些對象比較複雜龐大而且高度類似(具備相同的功能)的時候,咱們就能夠採用工廠模式統一管理這些對象的建立。這對調用者來講更加的方便直觀,並且也更加安全,由於工廠是預先設計好的,當知足工廠的生產條件後纔會生產產品。相反,若是是比較簡單的對象,那就徹底不必採起這種方式,直接new就好了。設計模式
工廠模式大多在框架中常見,由於它主要是爲調用者(咱們這些普通的開發人員)提供一個建立對象的出口,這些工廠類最大的特色就是它們的名字很明顯—xxxFactory。例如鏈接各類數據庫的ConnectionFactory,日誌的LoggerFactory,Spring中核心的BeanFactory等等。固然,咱們也能夠本身設計出工廠類來管理本身的對象。安全
理論和生活中的例子說完了,接下來步入正題,怎麼在代碼中去使用工廠模式。其實每種設計模式都能在生活中找到它們的例子,固然更能夠說代碼自己就是現實的一種抽象。上面說到,當一些對象高度類似即具備相同功能的時候,就可使用工廠模式去建立。而具備某種功能在Java中就是實現某個接口,因此是經過一些類共同實現某個接口,再由一個工廠類根據不一樣的條件(參數)來建立相應的對象。而返回的是接口類型,也就是說仍是一個抽象,這時調用接口裏定義的方法,根據Java的多態機制,會準確找到實現類並執行方法。這樣還有一個好處就是擴展性比較好,當有新的需求的時候就加一個實現類。框架
下面以一個手機工廠爲例子,經過UML類圖和示例代碼介紹工廠模式是如何設計並工做的。ide
1. 建立Mobile接口,並定義一個use的抽象方法spa
Mobile.java設計
public interface Mobile { void use(); }
2. 建立實現該接口的各個實現類日誌
Iphone.javacode
public class IPhone implements Mobile { @Override public void use() { System.out.println("裝逼"); } }
Nokia.java
public class Nokia implements Mobile{ @Override public void use() { System.out.println("擋子彈"); } }
Samsung.java
public class Samsung implements Mobile { @Override public void use() { System.out.println("爆炸"); } }
3. 建立一個手機工廠類MobileFactory,提供一個統一的出口getMobile方法來根據不一樣的條件建立相應的對象
MobileFactory.java
public class MobileFactory { public Mobile getMobile(String brand) { if (brand == null) { return null; } switch (brand) { case "iPhone" : return new IPhone(); case "Nokia" : return new Nokia(); case "Samsung" : return new Samsung(); default: throw new RuntimeException("本工廠暫不生產此品牌的手機!"); } } }
這裏咱們是根據不一樣的品牌來建立對應的手機對象,而實際中的條件要稍微複雜一些。能夠把方法改成static,這樣使用工廠類建立對象就不用先new工廠對象,比較簡單就不貼代碼了。
4. 使用該工廠類,經過傳遞不一樣的品牌參數來生成不一樣的對象
public class FactoryPatternDemo { public static void main(String[] args) { Mobile iPhone = MobileFactory.getMobile("iPhone"); iPhone.use(); Mobile nokia = MobileFactory.getMobile("Nokia"); nokia.use(); Mobile samsung = MobileFactory.getMobile("Samsung"); samsung.use(); } }
5. 輸出:
裝逼 擋子彈 爆炸
當咱們須要實現某個明確的功能而這種功能一般具備廣泛性時候,咱們就可使用工廠模式了。什麼是廣泛性呢,簡單來講就是這個功能提及來比較寬泛,可是實際上會有不一樣的明確實現。仍是舉一些例子:
例如要開發一個計算器,計算機的核心功能是計算,而計算這個功能是比較寬泛的,其實是有不少不一樣的明確實現,最多見的就是加減乘除。這時就能夠建立一個計算接口,再分別建立加減乘除四個實現類,最後建立一個計算器的工廠類,經過用戶傳來的運算符號決定具體採用哪一種運算。這樣之後擴展計算器的功能,例如對數指數微積分等高級運算,就徹底能夠按照這種模式去橫向擴展。
再好比咱們的系統如今須要實現一個報警功能,當代碼出現錯誤或系統崩潰時可以及時的通知相關人員。仍是老樣子,報警提及來是一回事,但具體實現上有不一樣的途徑:郵件、短信、站內信等等。這時也能夠採用工廠設計模式,根據不一樣的狀況採用不一樣的報警。
解耦、方便調用者建立對象、擴展性好。
每新增一個功能,就要加一個實現類,並須要修改工廠類的出口方法。這無疑會增長系統的複雜度,不利於維護。