上一篇文章(http://www.cnblogs.com/liaoweipeng/p/5768197.html)講了簡單工廠模式,但是簡單工廠模式存在一定的問題,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包-開放原則,所以,從設計角度考慮,有一定的問題,如何解決?就用到工廠方法模式,創建多個工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼。
工廠方法模式的概念
工廠方法模式(FACTORY METHOD)是一種常用的對象創建型設計模式,此模式的核心精神是封裝類中不變的部分,提取其中個性化善變的部分為獨立類,通過依賴注入以達到解耦、復用和方便后期維護拓展的目的。它的核心結構有四個角色,分別是抽象工廠;具體工廠;抽象產品;具體產品(百度百科)
工廠方法模式的UML圖
我特意去閱讀了《大話設計模式》《設計模式之禪》,把類圖在補充一下:當抽象工廠只有一個產品,變為工廠方法模式,當產品多個時候變為抽象工廠模式
這里在放2張簡單工廠和工廠方法模式的圖,形成對比:
工廠方法模式的代碼
我們接着簡單工廠模式的例子繼續講解工廠方法模式,如果在簡單工廠模式中需要增加一種不男不女的人,就需要修改工廠類中的生成方法了,雖然可以實現我們需要的結果,但是違背了java的開放-閉包的原則。我們根據前面的例子做一改造。
/** * This is factory patter package */ package com.roc.factory; /** * 產品的抽象接口 人類 * @author liaowp * */ public interface Human { public void say(); }
/** * This is factory patter package */ package com.roc.factory; /** * man 男人 * @author liaowp * */ public class Man implements Human { /* say method * @see com.roc.factory.Human#say() */ @Override public void say() { System.out.println("男人"); } }
/** * This is factory patter package */ package com.roc.factory; /**女人 * @author liaowp * */ public class Woman implements Human { /* say method * @see com.roc.factory.Human#say() */ @Override public void say() { System.out.println("女人"); } }
前面的代碼是一樣的,現在我們需要為一種人創建一個工廠類,既然每一個人都有自己的工廠類,那是不是可以抽一個類呢,對的,我們就抽出一個工廠接口來。
package com.roc.factory; /** * 工廠接口類 * @author liaowp * */ public interface Factory { public Human crateMan(); }
創造男人的工廠類
package com.roc.factory; /** * 創造男人工廠類 * @author liaowp * */ public class ManFactory implements Factory{ public Human crateMan() { return new Man(); } }
創造女人的工廠類
package com.roc.factory; /** * 創造女人工廠類 * @author liaowp * */ public class WomanFactory implements Factory{ @Override public Human crateMan() { // TODO Auto-generated method stub return new Woman(); } }
客戶端類
package com.roc.factory; /** * 抽象工廠測試 * @author liaowp * */ public class Client { public static void main(String[] args) { Factory factory=new ManFactory(); Human man2=factory.crateMan(); man2.say(); } }
改造完成,經過我這么一改造,你現在知道怎么增加創造不男不女的人嗎?這樣一改造你需要增加任何的類型都只需要增加一個工廠類,一個產品類。然后在客戶端寫出新的調用。完全符合了java的開發與閉包原則。
應用場景