轉載請註明出處:http://blog.csdn.net/singwhatiwanna/article/details/17428923java
說明:博主虛心接受你們的抨擊,批評,指正編程
我一直想介紹下工廠模式,我曾經搞過J2EE,用的是輕量級SSH框架,其中Spring有IOC概念,能夠稱之爲控制反轉或者依賴注入,在系統開發中,IOC能夠很好的替代工廠模式。若干年前,我只用過IOC,並無用過工廠模式,可是工廠模式這個概念倒是給我留下了深深的印象,畢竟,它是我所據說過第一個設計模式,我想它應該是很強大的吧。可是,事情不是我想的那個樣子的,在我以前所參與的項目(Android)中幾乎沒有工廠模式的身影,僅僅是有一個項目採用了簡單工廠模式去管理全部的業務管理器。後來,我開始仔細研究工廠模式,發現工廠模式是讓我失望的。工廠模式有三種實現方式:簡單工廠、工廠方法和抽象廣場,除了簡單工廠我還發現了一點使用價值外,後二者我基本沒發現有啥可以使用價值。也許個人理解還不夠透徹,可是目前網上存在的大部分介紹工廠模式的文章都體現了一點:華而不實,難以實際應用。一篇文章不能清晰的介紹一個概念,不能清晰的說明爲何要使用這個東西以及如何使用這個東西,那麼這篇文章不算好文章的。我目前所看到的關於工廠模式的介紹都是不充分的,包括我寫的這篇,期待真正的好文章出現。下面將介紹簡單工廠模式以及一個實際項目中使用的例子,後面我將會簡單闡述個人觀點:爲何工廠模式是華而不實的。設計模式
直接目的:避免在代碼中出現大量的new關鍵字緩存
根本目的:將對象的建立統一塊兒來便於維護和總體把控框架
這一點能夠理解,加入你在項目中new了某個對象100次,一年後因爲業務邏輯變動,構造方法多了一個參數,你會怎麼辦?你應該會這麼作:找到這100個對象new的地方,用新的構造方法來建立對象,你重複勞動了100次,假如採用工廠模式,你只用改一次:把建立工廠給改一下就行了。這就是工廠模式最簡單最直接的好處。ide
下面是最多見的一個示範,其實它的原理就是面向對象中的多態+接口編程,雖然返回的都是Car類型,可是drive的時候會調用真正的實例中的對應方法。按照抽象類和接口的意義歸屬,Car應該被定義成抽象類,由於Benz、Bmw和Car的關係是繼承關係,而接口表示的一組行爲。可是,爲何這裏還要定義成接口,是由於Java和.NET不支持多繼承,若是繼承了Car,就沒法繼承其餘類,有時候業務須要必須繼承其餘類,這個時候代碼就不能用了。固然,C++中支持多繼承,所以能夠在C++中使用抽象類,另外C++沒接口的概念,但你能夠模擬接口。這裏只介紹簡單工廠模式,至於剩下兩種工廠模式,我以爲更沒有使用價值。模塊化
interface Car { void drive(); } class Benz implements Car { @Override public void drive() { System.out.println("drive Benz"); } } class Bmw implements Car { @Override public void drive() { System.out.println("drive Bmw"); } } class CarFactory { public static Car creator(String carType) { if (carType.equals("Benz")) { return new Benz(); } else if (carType.equals("Bmw")) { return new Bmw(); } else { throw new UnsupportedOperationException("car with type" + carType + " is not supported."); } } } public class A { public static void main(String args[]) { Car benz = CarFactory.creator("Benz"); benz.drive(); Car bmw = CarFactory.creator("Bmw"); bmw.drive(); } }
上述代碼是沒啥用的,看一個實際使用的例子。下面這個工廠模式的意義在於可以統一管理全部的業務管理器,僅此而已。spa
/** * 管理器的工程,初始化全部業務的管理器 */ public class ManagerFactory { // 緩存管理器實例的集合 private transient Map<Byte, IManager> mManagerMap = null; private static ManagerFactory sIntance = new ManagerFactory(); private ManagerFactory() { mManagerMap = new HashMap<Byte, IManager>(); } public ManagerFactory getInstance() { return sInstance; } /** * 獲取管理器實例 * * @param context 上下文 * @param id 管理器ID * @return 管理器實例 */ protected IManager getManager(final Context context, final byte id) { IManager manager = mManagerMap.get(mId); if (manager == null) { switch (id) { case DB_ID: manager = new DBManager(context); break; case DOWNLOAD_ID: manager = new DownloadManager(context); break; case NETWORK_ID: manager = new NetworkManager(); break; case IMAGE_ID: manager = new ImageManager(); break; default: break; } mManagerMap.put(id, manager); } return manager; } }
優勢:將對象的建立統一塊兒來便於維護和總體把控,對擴展開放,對修改封閉
.net
缺點:耦合性提升,因爲工廠類集中了全部實例的建立邏輯,違反了高內聚責任分配原則,將所有建立邏輯集中到了一個工廠類中,這種對條件的判斷和對具體產品類型的判斷交錯在一塊兒,很難避免模塊功能的蔓延,對系統的維護和擴展很是不利。設計
從工廠模式的示例能夠看出:工廠模式須要類實現它的接口而且在業務內部存在明顯的繼承關係,好比汽車和奔馳寶馬的關係。而繼承關係每每存在於模型之間,業務之間很難存在繼承關係,所以若是業務內部或者業務之間沒有這種顯式的繼承關係該咋辦?就算業務內部有繼承關係,各個業務交給你統一管理,這樣就會提升代碼的耦合性,當建立邏輯複雜的時候,工廠方法就很複雜,容易產生干擾。
能夠經過高度層次化和模塊化來提升系統的開閉性,而沒必要生硬地去套用工廠模式。