• <menu id="gyiem"><menu id="gyiem"></menu></menu>
  • <menu id="gyiem"><code id="gyiem"></code></menu>

    Java設計模式(二) 工廠方法模式

    原創文章,轉載請務必將下面這段話置于文章開頭處(保留超鏈接)。
    本文轉發自技術世界原文鏈接 http://www.luozeyang.com/design_pattern/factory_method/

    工廠方法模式解決的問題

    上文《簡單工廠模式不簡單》中提到,簡單工廠模式有如下缺點,而工廠方法模式可以解決這些問題

    • 由于工廠類集中了所有實例的創建邏輯,這就直接導致一旦這個工廠出了問題,所有的客戶端都會受到牽連。
    • 由于簡單工廠模式的產品是基于一個共同的抽象類或者接口,這樣一來,產品的種類增加的時候,即有不同的產品接口或者抽象類的時候,工廠類就需要判斷何時創建何種接口的產品,這就和創建何種種類的產品相互混淆在了一起,違背了單一職責原則,導致系統喪失靈活性和可維護性。
    • 簡單工廠模式違背了“開放-關閉原則”,因為當我們新增加一個產品的時候必須修改工廠類,相應的工廠類就需要重新編譯一遍。
    • 簡單工廠模式由于使用了靜態工廠方法,造成工廠角色無法形成基于繼承的等級結構。

    工廠方法模式

    工廠方法模式介紹

    工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫多態工廠模式或者虛擬構造器模式。在工廠方法模式中,工廠父類定義創建產品對象的公共接口,具體的工廠子類負責創建具體的產品對象。每一個工廠子類負責創建一種具體產品。

    工廠方法模式類圖

    工廠模式類圖如下 (點擊可查看大圖)
    Factory Method Pattern Class Diagram

    工廠方法模式角色劃分

    • 抽象產品(或者產品接口),如上圖中IUserDao
    • 具體產品,如上圖中的MySQLUserDao,PostgreSQLUserDao和OracleUserDao
    • 抽象工廠(或者工廠接口),如IFactory
    • 具體工廠,如MySQLFactory,PostgreSQLFactory和OracleFactory

    工廠方法模式使用方式

    如簡單工廠模式直接使用靜態工廠方法創建產品對象不同,在工廠方法,客戶端通過實例化具體的工廠類,并調用其創建實例接口創建具體產品類的實例。根據依賴倒置原則,具體工廠類的實例由工廠接口引用(客戶端依賴于抽象工廠而非具體工廠),具體產品的實例由產品接口引用(客戶端和工廠依賴于抽象產品而非具體產品)。具體調用代碼如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.jasongj.client;

    import com.jasongj.dao.IUserDao;
    import com.jasongj.factory.IDaoFactory;
    import com.jasongj.factory.MySQLDaoFactory;

    public class Client {

    public static void main(String[] args) {
    IDaoFactory factory = new MySQLDaoFactory();
    IUserDao userDao = factory.createUserDao();
    userDao.getUser("admin");

    }

    }

    工廠方法模式示例代碼

    本文所述工廠方法模式示例代碼可從作者Github下載

    工廠方法模式優點

    • 因為每個具體工廠類只負責創建產品,沒有簡單工廠中的邏輯判斷,因此符合單一職責原則。
    • 與簡單工廠模式不同,工廠方法并不使用靜態工廠方法,可以形成基于繼承的等級結構。
    • 新增一種產品時,只需要增加相應的具體產品類和相應的工廠子類即可,相比于簡單工廠模式需要修改判斷邏輯而言,工廠方法模式更符合開-閉原則。

    工廠方法模式缺點

    • 添加新產品時,除了增加新產品類外,還要提供與之對應的具體工廠類,系統類的個數將成對增加,在一定程度上增加了系統的復雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。
    • 雖然保證了工廠方法內的對修改關閉,但對于使用工廠方法的類,如果要換用另外一種產品,仍然需要修改實例化的具體工廠。
    • 一個具體工廠只能創建一種具體產品

    簡單工廠模式與OOP原則

    已遵循的原則

    • 依賴倒置原則
    • 迪米特法則
    • 里氏替換原則
    • 接口隔離原則
    • 單一職責原則(每個工廠只負責創建自己的具體產品,沒有簡單工廠中的邏輯判斷)
    • 開閉原則(增加新的產品,不像簡單工廠那樣需要修改已有的工廠,而只需增加相應的具體工廠類)

    未遵循的原則

    • 開閉原則(雖然工廠對修改關閉了,但更換產品時,客戶代碼還是需要修改)

    Java設計模式系列

    郭俊 Jason wechat
    歡迎關注作者微信公眾號【大數據架構】
    您的贊賞將支持作者繼續原創分享
    速赢彩app 吉林长春 | 天水 | 惠州 | 沭阳 | 灌南 | 铜川 | 毕节 | 昌吉 | 惠东 | 枣阳 | 云南昆明 | 玉树 | 灌南 | 丽江 | 吉林长春 | 瑞安 | 海南海口 | 文昌 | 泗洪 | 河源 | 慈溪 | 徐州 | 白银 | 河源 | 六安 | 眉山 | 咸阳 | 丽水 | 定西 | 鸡西 | 柳州 | 鸡西 | 吉林 | 宁国 | 贺州 | 云浮 | 简阳 | 长垣 | 邵阳 | 衢州 | 黄石 | 抚州 | 汕尾 | 鞍山 | 昆山 | 曹县 | 阿克苏 | 防城港 | 常德 | 河南郑州 | 淮安 | 玉环 | 五家渠 | 任丘 | 鄂州 | 景德镇 | 武威 | 衢州 | 阿拉善盟 | 贵港 | 新沂 | 九江 | 章丘 | 吉林 | 永州 | 芜湖 | 榆林 | 海宁 | 襄阳 | 湖北武汉 | 海宁 | 新沂 | 益阳 | 玉林 | 金昌 | 南京 | 克拉玛依 | 防城港 | 招远 | 大庆 | 玉树 | 云南昆明 | 阿拉善盟 | 周口 | 苍南 | 安徽合肥 | 安吉 | 博尔塔拉 | 威海 | 石狮 | 昭通 | 乌海 | 大庆 | 新泰 | 酒泉 | 桐乡 | 咸阳 | 香港香港 | 盐城 | 大庆 | 五家渠 | 山南 | 曹县 | 固原 | 达州 | 宣城 | 章丘 | 焦作 | 海门 | 辽阳 | 鸡西 | 江苏苏州 | 天水 |