我的博客原文
建立型模式:工廠方法java
姓名:工廠方法git
英文名:Factory method Patterngithub
價值觀:擴展是個人專屬設計模式
我的介紹:框架
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses. (定義一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類。)
(來自《設計模式之禪》)ide
還記得上一篇 單例模式 中的故事麼?小明開着汽車去旅遊、去學校、去聚會。這一次仍是延續小明的故事,一個故事能講 2 個設計模式,不容易呀。。。(每次想故事都想破腦殼,每一篇文章至少有 3 個故事從腦子裏閃過,但最終留下的只有一個適合,爲了就是能比較清晰簡單的說明設計模式中的關鍵要點。)工具
小明家裏之前不算很富裕,可是仍是有一個不錯的車庫,什麼汽車、摩托車、自行車啥的都放在這個車庫裏。小明每次要出去,都會到車庫裏面挑合適的車出發。好比,小明最近期末考試了,騎摩托車去學校考試,考完試以後,小明就準備去旅遊,此次決定自駕遊,開着本身家的小汽車去。這個場景咱們用代碼描述下。設計
public class SimpleFactoryTest { public static void main(String[] args) { XiaoMing xiaoMing = new XiaoMing(); // 小明騎摩托車去學校 IVehicle motorcycle = GarageFactory.getVehicle("motorcycle"); xiaoMing.goToSchool(motorcycle); // 小明開汽車去旅遊 IVehicle car = GarageFactory.getVehicle("car"); xiaoMing.travel(car); } } /** * 車庫 */ class GarageFactory { public static IVehicle getVehicle(String type) { if ("car".equals(type)) { return new Car(); } else if ("motorcycle".equals(type)) { return new Motorcycle(); } throw new IllegalArgumentException("請輸入車類型"); } } /** * 交通工具 */ interface IVehicle { void run(); } /** * 汽車 */ class Car implements IVehicle { @Override public void run() { System.out.println("開汽車去。。。。"); } } /** * 摩托車 */ class Motorcycle implements IVehicle { @Override public void run() { System.out.println("騎摩托車去。。。。"); } } class XiaoMing { public void goToSchool(IVehicle vehicle) { System.out.println("小明去學校"); vehicle.run(); } public void travel(IVehicle vehicle) { System.out.println("小明去旅遊"); vehicle.run(); } }
上面代碼看懂了麼? 小明家裏有一個車庫 GarageFactory,裏面放着汽車 Car 和摩托車 Motorcycle,小明要出去的時候,就到車庫選擇車,經過傳遞參數給 GarageFactory.getVehicle(),指明要什麼車,而後小明就騎着車出發了。code
這個代碼真正的術語叫:簡單工廠模式(Simple Factory Pattern),也叫作靜態工廠模式。它是工廠方法中的一個實現方式,從字面理解就能夠知道,它是最簡單的工廠方法實現方式。它有一點點小缺陷,就是擴展性不夠好,在上面代碼中,小明只能騎摩托車或者開汽車,若是小明要騎單車出去呢?勢必得在 GarageFactory 中添加 if 是自行車的邏輯。這違反了哪條規則了?是否是那個容許擴展,拒絕修改的開閉原則?對象
不是說簡單工廠這種實現方式很差,而是擴展性不夠,在平時的開發中,簡單工廠模式也用得很多。在這個小明家裏車很少的狀況下,用一個車庫也是合適的。
小明老爸近幾年賺了很多,車迷的兩父子一直買車,家裏的車愈來愈多,這時候,他們決定多建幾個車庫,按車類型放置。好比,有一個汽車庫,一個摩托車庫。這時候小明要開汽車就去汽車庫,要騎摩托車就去摩托車庫。代碼實現以下。
public class FactoryMethodTest { public static void main(String[] args) { XiaoMing xiaoMing = new XiaoMing(); // 小明騎摩托車去學校 VehicleGarage motorcycleGarage = new MotorcycleGarage(); IVehicle motorcycle = motorcycleGarage.getVehicle(); xiaoMing.goToSchool(motorcycle); // 小明開汽車去旅遊 VehicleGarage carGarage = new CarGarage(); IVehicle car = carGarage.getVehicle(); xiaoMing.travel(car); } } interface VehicleGarage { IVehicle getVehicle(); } /** * 汽車車庫 */ class CarGarage implements VehicleGarage { @Override public IVehicle getVehicle() { return new Car(); } } /** * 摩托車車庫 */ class MotorcycleGarage implements VehicleGarage { @Override public IVehicle getVehicle() { return new Motorcycle(); } }
上面代碼重用了簡單工廠實現方式的交通接口以及摩托車和汽車的實現類。代碼中有 2 個車庫,一個是汽車車庫 CarGarage,一個是摩托車庫 MotorcycleGarage。若是小明要騎自行車,只須要建一個自行車車庫,徹底不用去修改汽車車庫或者摩托車車庫,就很是符合開閉原則,擴展性大大的提升。
工廠方法模式能夠說在你能想到的開源框架源碼中一定會使用的一個設計模式,由於開源框架很重要一點就是要有擴展性,而工廠方法模式偏偏具備可擴展性。弄懂了工廠方法模式,之後看開源代碼就很駕輕就熟啦。
參考資料:《大話設計模式》、《Java設計模式》、《設計模式之禪》、《研磨設計模式》、《Head First 設計模式》
但願文章對您有所幫助,設計模式系列會持續更新,感興趣的同窗能夠關注公衆號 LieBrother,第一時間獲取文章推送閱讀,也能夠一塊兒交流,交個朋友。