工廠模式

工廠模式是我們最常用的實例化對象模式了正歼,是用工廠方法代替new操作的一種模式辐马。通常我們所說的工廠模式是指工廠方法模式,它也是使用頻率最高的工廠模式局义。工廠模式在Java程序系統(tǒng)可以說是隨處可見喜爷。因為工廠模式就相當于創(chuàng)建實例對象的new,我們經(jīng)常要根據(jù)類Class生成實例對象萄唇,如A a=new A() 工廠模式也是用來創(chuàng)建實例對象的檩帐,所以以后new時就要多個心眼,是否可以考慮使用工廠模式另萤,雖然這樣做湃密,可能多做一些工作,但會給你系統(tǒng)帶來更大的可擴展性和盡量少的修改量四敞。

工廠模式的作用

工廠模式(包括簡單工廠模式泛源、工廠方法模式和抽象工廠模式)到底有什么用,很多時候通過反射機制就可以很靈活地創(chuàng)建對象目养,為什么還要工廠俩由?

與一個對象有關(guān)的原則有三類:

  1. 對象本身所具有的職責
  2. 創(chuàng)建對象的職責
  3. 使用對象的職責

對象本身的職責很好理解,就是對象自身所具有的一些數(shù)據(jù)和行為癌蚁,可通過一些公開的方法來實現(xiàn)它的職責幻梯。在本文中,我們將簡單討論一下對象的創(chuàng)建職責和使用職責努释。

在Java語言中碘梢,我們通常有以下幾種創(chuàng)建對象的方式:

  1. 使用new關(guān)鍵字直接創(chuàng)建對象;
  2. 通過反射機制創(chuàng)建對象伐蒂;
  3. 通過clone()方法創(chuàng)建對象煞躬;
  4. 通過工廠類創(chuàng)建對象。

毫無疑問逸邦,在客戶端代碼中直接使用new關(guān)鍵字是最簡單的一種創(chuàng)建對象的方式恩沛,但是它的靈活性較差,下面通過一個簡單的示例來加以說明:

class LoginAction {
    private UserDAO udao;
    
    public LoginAction() {
        udao = new JDBCUserDAO(); //創(chuàng)建對象
    }
    
    public void execute() {
        //其他代碼
        udao.findUserById(); //使用對象
        //其他代碼
    }
}

在LoginAction類中定義了一個UserDAO類型的對象udao缕减,在LoginAction的構(gòu)造函數(shù)中創(chuàng)建了JDBCUserDAO類型的udao對象雷客,并在execute()方法中調(diào)用了udao對象的findUserById()方法,這段代碼看上去并沒有什么問題桥狡。下面我們來分析一下LoginAction和UserDAO之間的關(guān)系搅裙,LoginAction類負責創(chuàng)建了一個UserDAO子類的對象并使用UserDAO的方法來完成相應的業(yè)務處理皱卓,也就是說LoginAction即負責udao的創(chuàng)建又負責udao的使用,創(chuàng)建對象和使用對象的職責耦合在一起部逮,這樣的設(shè)計會導致一個很嚴重的問題:如果在LoginAction中希望能夠使用UserDAO的另一個子類如HibernateUserDAO類型的對象娜汁,必須修改LoginAction類的源代碼,違反了“開閉原則”兄朋。如何解決該問題掐禁?

最常用的一種解決方法是將udao對象的創(chuàng)建職責從LoginAction類中移除,在LoginAction類之外創(chuàng)建對象颅和,那么誰來負責創(chuàng)建UserDAO對象呢穆桂?答案是:工廠類。通過引入工廠類融虽,客戶類(如LoginAction)不涉及對象的創(chuàng)建,對象的創(chuàng)建者也不會涉及對象的使用灼芭。引入工廠類UserDAOFactory之后的結(jié)構(gòu)如圖1所示:

enter image description here

工廠類的引入將降低因為產(chǎn)品或工廠類改變所造成的維護工作量有额。如果UserDAO的某個子類的構(gòu)造函數(shù)發(fā)生改變或者要需要添加或移除不同的子類,只要維護UserDAOFactory的代碼彼绷,而不會影響到LoginAction巍佑;如果UserDAO的接口發(fā)生改變,例如添加寄悯、移除方法或改變方法名萤衰,只需要修改LoginAction,不會給UserDAOFactory帶來任何影響猜旬。
在所有的工廠模式中脆栋,我們都強調(diào)一點:兩個類A和B之間的關(guān)系應該僅僅是A創(chuàng)建B或是A使用B,而不能兩種關(guān)系都有洒擦。將對象的創(chuàng)建和使用分離椿争,也使得系統(tǒng)更加符合“單一職責原則”,有利于對功能的復用和系統(tǒng)的維護熟嫩。

此外秦踪,將對象的創(chuàng)建和使用分離還有一個好處:防止用來實例化一個類的數(shù)據(jù)和代碼在多個類中到處都是,可以將有關(guān)創(chuàng)建的知識搬移到一個工廠類中掸茅,這在Joshua Kerievsky的《重構(gòu)與模式》一書中有專門的一節(jié)來進行介紹椅邓。因為有時候我們創(chuàng)建一個對象不只是簡單調(diào)用其構(gòu)造函數(shù),還需要設(shè)置一些參數(shù)昧狮,可能還需要配置環(huán)境景馁,如果將這些代碼散落在每一個創(chuàng)建對象的客戶類中,勢必會出現(xiàn)代碼重復陵且、創(chuàng)建蔓延的問題裁僧,而這些客戶類其實無須承擔對象的創(chuàng)建工作个束,它們只需使用已創(chuàng)建好的對象就可以了。此時聊疲,可以引入工廠類來封裝對象的創(chuàng)建邏輯和客戶代碼的實例化/配置選項塘装。

使用工廠類還有一個“不是特別明顯的”優(yōu)點幔翰,一個類可能擁有多個構(gòu)造函數(shù),而在Java、C#等語言中構(gòu)造函數(shù)名字都與類名相同况鸣,客戶端只能通過傳入不同的參數(shù)來調(diào)用不同的構(gòu)造函數(shù)創(chuàng)建對象,從構(gòu)造函數(shù)和參數(shù)列表中也許大家根本不了解不同構(gòu)造函數(shù)所構(gòu)造的產(chǎn)品的差異忙厌。但如果將對象的創(chuàng)建過程封裝在工廠類中铃岔,我們可以提供一系列名字完全不同的工廠方法,每一個工廠方法對應一個構(gòu)造函數(shù)门岔,客戶端可以以一種更加可讀爱致、易懂的方式來創(chuàng)建對象,而且寒随,從一組工廠方法中選擇一個意義明確的工廠方法糠悯,比從一組名稱相同參數(shù)不同的構(gòu)造函數(shù)中選擇一個構(gòu)造函數(shù)要方便很多。

那么妻往,有人可能會問互艾,是否需要為設(shè)計中的每一個類都配備一個工廠類?答案是:具體情況具體分析讯泣。如果產(chǎn)品類很簡單纫普,而且不存在太多變數(shù),其構(gòu)造過程也很簡單好渠,此時無須為其提供工廠類昨稼,直接在使用之前實例化即可,例如Java語言中的String類晦墙,我們就無須為它專門提供一個StringFactory悦昵,這樣做反而有點像殺雞用牛刀,大材小用晌畅,而且會導致工廠泛濫但指,增加系統(tǒng)的復雜度。

工廠模式是為了將對象的創(chuàng)建和使用分離抗楔,也使得系統(tǒng)更加符合“單一職責原則”棋凳,有利于對功能的復用和系統(tǒng)的維護,防止用來實例化一個類的數(shù)據(jù)和代碼在多個類中到處都是连躏,可以將有關(guān)創(chuàng)建的知識搬移到一個工廠類中剩岳。

轉(zhuǎn)載:創(chuàng)建對象與使用對象——談談工廠的作用

簡單工廠模式

簡單工廠模式(Simple Factory Pattern):定義一個工廠類,它可以根據(jù)參數(shù)的不同返回不同類的實例入热,被創(chuàng)建的實例通常都具有共同的父類拍棕。因為在簡單工廠模式中用于創(chuàng)建實例的方法是靜態(tài)(static)方法晓铆,因此簡單工廠模式又被稱為靜態(tài)工廠方法(Static Factory Method)模式,它屬于類創(chuàng)建型模式绰播。

簡單工廠模式的要點在于:當你需要什么骄噪,只需要傳入一個正確的參數(shù),就可以獲取你所需要的對象蠢箩,而無須知道其創(chuàng)建細節(jié)链蕊。簡單工廠模式結(jié)構(gòu)比較簡單,其核心是工廠類的設(shè)計, 其結(jié)構(gòu)如下圖所示谬泌。

image.png

在簡單工廠模式結(jié)構(gòu)圖中包含如下幾個角色:

  • Factory(工廠角色):工廠角色即工廠類滔韵,它是簡單工廠模式的核心,負責實現(xiàn)創(chuàng)建所有產(chǎn)品實例的內(nèi)部邏輯掌实;工廠類可以被外界直接調(diào)用陪蜻,創(chuàng)建所需的產(chǎn)品對象;在工廠類中提供了靜態(tài)的工廠方法factoryMethod()贱鼻,它的返回類型為抽象產(chǎn)品類型Product囱皿。
  • Product(抽象產(chǎn)品角色):它是工廠類所創(chuàng)建的所有對象的父類,封裝了各種產(chǎn)品對象的公有方法忱嘹,它的引入將提高系統(tǒng)的靈活性,使得在工廠類中只需定義一個通用的工廠方法耕渴,因為所有創(chuàng)建的具體產(chǎn)品對象都是其子類對象拘悦。
  • ConcreteProduct(具體產(chǎn)品角色):它是簡單工廠模式的創(chuàng)建目標,所有被創(chuàng)建的對象都充當這個角色的某個具體類的實例橱脸。每一個具體產(chǎn)品角色都繼承了抽象產(chǎn)品角色础米,需要實現(xiàn)在抽象產(chǎn)品中聲明的抽象方法。

在簡單工廠模式中添诉,客戶端通過工廠類來創(chuàng)建一個產(chǎn)品類的實例屁桑,而無須直接使用new關(guān)鍵字來創(chuàng)建對象,它是工廠模式家族中最簡單的一員栏赴。
在使用簡單工廠模式時蘑斧,首先需要對產(chǎn)品類進行重構(gòu),不能設(shè)計一個包羅萬象的產(chǎn)品類须眷,而需根據(jù)實際情況設(shè)計一個產(chǎn)品層次結(jié)構(gòu)竖瘾,將所有產(chǎn)品類公共的代碼移至抽象產(chǎn)品類,并在抽象產(chǎn)品類中聲明一些抽象方法花颗,以供不同的具體產(chǎn)品類來實現(xiàn)捕传,典型的抽象產(chǎn)品類代碼如下所示:

abstract class Product {
    //所有產(chǎn)品類的公共業(yè)務方法
    public void methodSame() {
        //公共方法的實現(xiàn)
    }

    //聲明抽象業(yè)務方法
    public abstract void methodDiff();
}

在具體產(chǎn)品類中實現(xiàn)了抽象產(chǎn)品類中聲明的抽象業(yè)務方法,不同的具體產(chǎn)品類可以提供不同的實現(xiàn)扩劝,典型的具體產(chǎn)品類代碼如下所示:

class ConcreteProduct extends Product {
    //實現(xiàn)業(yè)務方法
    public void methodDiff() {
        //業(yè)務方法的實現(xiàn)
    }
}

簡單工廠模式的核心是工廠類庸论,在沒有工廠類之前职辅,客戶端一般會使用new關(guān)鍵字來直接創(chuàng)建產(chǎn)品對象,而在引入工廠類之后聂示,客戶端可以通過工廠類來創(chuàng)建產(chǎn)品域携,在簡單工廠模式中,工廠類提供了一個靜態(tài)工廠方法供客戶端使用催什,根據(jù)所傳入的參數(shù)不同可以創(chuàng)建不同的產(chǎn)品對象涵亏,典型的工廠類代碼如下所示:

class Factory {
    //靜態(tài)工廠方法
    public static Product getProduct(String arg) {
        Product product = null;
        if (arg.equalsIgnoreCase("A")) {
            product = new ConcreteProductA();
            //初始化設(shè)置product
        }
        else if (arg.equalsIgnoreCase("B")) {
            product = new ConcreteProductB();
            //初始化設(shè)置product
        }
        return product;
    }
}

在客戶端代碼中,我們通過調(diào)用工廠類的工廠方法即可得到產(chǎn)品對象蒲凶,典型代碼如下所示:

class Client {
    public static void main(String args[]) {
        Product product; 
        product = Factory.getProduct("A"); //通過工廠類創(chuàng)建產(chǎn)品對象
        product.methodSame();
        product.methodDiff();
    }
}

簡單工廠模式總結(jié):

簡單工廠模式提供了專門的工廠類用于創(chuàng)建對象气筋,將對象的創(chuàng)建和對象的使用分離開,它作為一種最簡單的工廠模式在軟件開發(fā)中得到了較為廣泛的應用旋圆。

  • 優(yōu)點

    • 工廠類包含必要的判斷邏輯宠默,可以決定在什么時候創(chuàng)建哪一個產(chǎn)品類的實例,客戶端可以免除直接創(chuàng)建產(chǎn)品對象的職責灵巧,而僅僅“消費”產(chǎn)品搀矫,簡單工廠模式實現(xiàn)了對象創(chuàng)建和使用的分離。
    • 客戶端無須知道所創(chuàng)建的具體產(chǎn)品類的類名刻肄,只需要知道具體產(chǎn)品類所對應的參數(shù)即可瓤球,對于一些復雜的類名,通過簡單工廠模式可以在一定程度減少使用者的記憶量敏弃。
    • 通過引入配置文件卦羡,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產(chǎn)品類,在一定程度上提高了系統(tǒng)的靈活性麦到。
  • 缺點

    • 由于工廠類集中了所有產(chǎn)品的創(chuàng)建邏輯绿饵,職責過重,一旦不能正常工作瓶颠,整個系統(tǒng)都要受到影響拟赊。
    • 使用簡單工廠模式勢必會增加系統(tǒng)中類的個數(shù)(引入了新的工廠類),增加了系統(tǒng)的復雜度和理解難度粹淋。
    • 系統(tǒng)擴展困難吸祟,一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類型較多時桃移,有可能造成工廠邏輯過于復雜欢搜,不利于系統(tǒng)的擴展和維護。
    • 系統(tǒng)擴展困難谴轮,一旦添加新產(chǎn)品就不得不修改工廠邏輯炒瘟,在產(chǎn)品類型較多時,有可能造成工廠邏輯過于復雜第步,不利于系統(tǒng)的擴展和維護疮装。
  • 適用場景

    • 工廠類負責創(chuàng)建的對象比較少缘琅,由于創(chuàng)建的對象較少,不會造成工廠方法中的業(yè)務邏輯太過復雜廓推。
    • 工廠類負責創(chuàng)建的對象比較少刷袍,由于創(chuàng)建的對象較少,不會造成工廠方法中的業(yè)務邏輯太過復雜樊展。

轉(zhuǎn)載:工廠三兄弟之簡單工廠模式(二)

工廠方法模式

簡單工廠模式雖然簡單呻纹,但存在一個很嚴重的問題。當系統(tǒng)中需要引入新產(chǎn)品時专缠,由于靜態(tài)工廠方法通過所傳入?yún)?shù)的不同來創(chuàng)建不同的產(chǎn)品雷酪,這必定要修改工廠類的源代碼,將違背“開閉原則”涝婉,如何實現(xiàn)增加新產(chǎn)品而不影響已有代碼哥力?工廠方法模式應運而生.

在工廠方法模式中,我們不再提供一個統(tǒng)一的工廠類來創(chuàng)建所有的產(chǎn)品對象墩弯,而是針對不同的產(chǎn)品提供不同的工廠吩跋,系統(tǒng)提供一個與產(chǎn)品等級結(jié)構(gòu)對應的工廠等級結(jié)構(gòu)。

工廠方法模式(Factory Method Pattern):定義一個用于創(chuàng)建對象的接口渔工,讓子類決定將哪一個類實例化锌钮。工廠方法模式讓一個類的實例化延遲到其子類。工廠方法模式又簡稱為工廠模式(Factory Pattern)引矩,又可稱作虛擬構(gòu)造器模式(Virtual Constructor Pattern)或多態(tài)工廠模式(Polymorphic Factory Pattern)轧粟。工廠方法模式是一種類創(chuàng)建型模式。

工廠方法模式提供一個抽象工廠接口來聲明抽象工廠方法脓魏,而由其子類來具體實現(xiàn)工廠方法,創(chuàng)建具體的產(chǎn)品對象通惫。工廠方法模式結(jié)構(gòu)如圖所示:

image.png

在工廠方法模式結(jié)構(gòu)圖中包含如下幾個角色:

  • Product(抽象產(chǎn)品):它是定義產(chǎn)品的接口茂翔,是工廠方法模式所創(chuàng)建對象的超類型,也就是產(chǎn)品對象的公共父類履腋。
  • ConcreteProduct(具體產(chǎn)品):它實現(xiàn)了抽象產(chǎn)品接口珊燎,某種類型的具體產(chǎn)品由專門的具體工廠創(chuàng)建,具體工廠和具體產(chǎn)品之間一一對應遵湖。
  • Factory(抽象工廠):在抽象工廠類中悔政,聲明了工廠方法(Factory Method),用于返回一個產(chǎn)品延旧。抽象工廠是工廠方法模式的核心谋国,所有創(chuàng)建對象的工廠類都必須實現(xiàn)該接口。
  • ConcreteFactory(具體工廠):它是抽象工廠類的子類迁沫,實現(xiàn)了抽象工廠中定義的工廠方法芦瘾,并可由客戶端調(diào)用捌蚊,返回一個具體產(chǎn)品類的實例。

與簡單工廠模式相比近弟,工廠方法模式最重要的區(qū)別是引入了抽象工廠角色缅糟,抽象工廠可以是接口,也可以是抽象類或者具體類祷愉,其典型代碼如下所示:


interface Factory {
    public Product factoryMethod();
}

在實際使用時窗宦,具體工廠類在實現(xiàn)工廠方法時除了創(chuàng)建具體產(chǎn)品對象之外,還可以負責產(chǎn)品對象的初始化工作以及一些資源和環(huán)境配置工作二鳄,例如連接數(shù)據(jù)庫赴涵、創(chuàng)建文件等。
在客戶端代碼中泥从,只需關(guān)心工廠類即可句占,不同的具體工廠可以創(chuàng)建不同的產(chǎn)品,典型的客戶端類代碼片段如下所示:

Factory factory;
factory = new ConcreteFactory(); //可以結(jié)合配置文件和反射機制來實現(xiàn)
Product product;
product = factory.factoryMethod();

可以通過配置文件來存儲具體工廠類ConcreteFactory的類名躯嫉,更換新的具體工廠時無須修改源代碼纱烘,系統(tǒng)擴展更為方便。

工廠方法模式總結(jié)

  • 優(yōu)點
    • 在工廠方法模式中祈餐,工廠方法用來創(chuàng)建客戶所需要的產(chǎn)品擂啥,同時還向客戶隱藏了哪種具體產(chǎn)品類將被實例化這一細節(jié),用戶只需要關(guān)心所需產(chǎn)品對應的工廠帆阳,無須關(guān)心創(chuàng)建細節(jié)哺壶,甚至無須知道具體產(chǎn)品類的類名。
    • 基于工廠角色和產(chǎn)品角色的多態(tài)性設(shè)計是工廠方法模式的關(guān)鍵蜒谤。它能夠讓工廠可以自主確定創(chuàng)建何種產(chǎn)品對象山宾,而如何創(chuàng)建這個對象的細節(jié)則完全封裝在具體工廠內(nèi)部。工廠方法模式之所以又被稱為多態(tài)工廠模式鳍徽,就正是因為所有的具體工廠類都具有同一抽象父類资锰。
    • 使用工廠方法模式的另一個優(yōu)點是在系統(tǒng)中加入新產(chǎn)品時,無須修改抽象工廠和抽象產(chǎn)品提供的接口阶祭,無須修改客戶端绷杜,也無須修改其他的具體工廠和具體產(chǎn)品,而只要添加一個具體工廠和具體產(chǎn)品就可以了濒募,這樣鞭盟,系統(tǒng)的可擴展性也就變得非常好,完全符合“開閉原則”瑰剃。
  • 缺點
    • 在添加新產(chǎn)品時齿诉,需要編寫新的具體產(chǎn)品類,而且還要提供與之對應的具體工廠類,系統(tǒng)中類的個數(shù)將成對增加鹃两,在一定程度上增加了系統(tǒng)的復雜度遗座,有更多的類需要編譯和運行,會給系統(tǒng)帶來一些額外的開銷俊扳。
    • 由于考慮到系統(tǒng)的可擴展性途蒋,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義馋记,增加了系統(tǒng)的抽象性和理解難度号坡,且在實現(xiàn)時可能需要用到DOM、反射等技術(shù)梯醒,增加了系統(tǒng)的實現(xiàn)難度宽堆。
  • 適用場景
    • 客戶端不知道它所需要的對象的類。在工廠方法模式中茸习,客戶端不需要知道具體產(chǎn)品類的類名畜隶,只需要知道所對應的工廠即可,具體的產(chǎn)品對象由具體工廠類創(chuàng)建号胚,可將具體工廠類的類名存儲在配置文件或數(shù)據(jù)庫中籽慢。
    • 抽象工廠類通過其子類來指定創(chuàng)建哪個對象。在工廠方法模式中猫胁,對于抽象工廠類只需要提供一個創(chuàng)建產(chǎn)品的接口箱亿,而由其子類來確定具體要創(chuàng)建的對象,利用面向?qū)ο蟮亩鄳B(tài)性和里氏代換原則弃秆,在程序運行時届惋,子類對象將覆蓋父類對象,從而使得系統(tǒng)更容易擴展菠赚。

參考:工廠三兄弟之工廠方法模式(三)

抽象工廠模式

抽象工廠模式(Abstract Factory Pattern):提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口脑豹,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式衡查,它是一種對象創(chuàng)建型模式瘩欺。

在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法用于產(chǎn)生多種不同類型的產(chǎn)品峡捡,這些產(chǎn)品構(gòu)成了一個產(chǎn)品族,抽象工廠模式結(jié)構(gòu)如圖所示:

image.png

在抽象工廠模式結(jié)構(gòu)圖中包含如下幾個角色:

  • AbstractFactory(抽象工廠):它聲明了一組用于創(chuàng)建一族產(chǎn)品的方法筑悴,每一個方法對應一種產(chǎn)品们拙。
  • ConcreteFactory(具體工廠):它實現(xiàn)了在抽象工廠中聲明的創(chuàng)建產(chǎn)品的方法,生成一組具體產(chǎn)品阁吝,這些產(chǎn)品構(gòu)成了一個產(chǎn)品族砚婆,每一個產(chǎn)品都位于某個產(chǎn)品等級結(jié)構(gòu)中。
  • AbstractProduct(抽象產(chǎn)品):它為每種產(chǎn)品聲明接口,在抽象產(chǎn)品中聲明了產(chǎn)品所具有的業(yè)務方法装盯。
  • ConcreteProduct(具體產(chǎn)品):它定義具體工廠生產(chǎn)的具體產(chǎn)品對象坷虑,實現(xiàn)抽象產(chǎn)品接口中聲明的業(yè)務方法。

在抽象工廠中聲明了多個工廠方法埂奈,用于創(chuàng)建不同類型的產(chǎn)品迄损,抽象工廠可以是接口,也可以是抽象類或者具體類账磺,其典型代碼如下所示:

class ConcreteFactory1 extends AbstractFactory {
        //工廠方法一
        public AbstractProductA createProductA() {
            return new ConcreteProductA1();
        }

        //工廠方法二
        public AbstractProductB createProductB() {
            return new ConcreteProductB1();
        }

        ……
}

與工廠方法模式一樣芹敌,抽象工廠模式也可為每一種產(chǎn)品提供一組重載的工廠方法,以不同的方式對產(chǎn)品對象進行創(chuàng)建垮抗。

具體工廠實現(xiàn)了抽象工廠氏捞,每一個具體的工廠方法可以返回一個特定的產(chǎn)品對象,而同一個具體工廠所創(chuàng)建的產(chǎn)品對象構(gòu)成了一個產(chǎn)品族冒版。

開閉原則”的傾斜性

在抽象工廠模式中液茎,增加新的產(chǎn)品族很方便,但是增加新的產(chǎn)品等級結(jié)構(gòu)很麻煩辞嗡,抽象工廠模式的這種性質(zhì)稱為“開閉原則”的傾斜性捆等。“開閉原則”要求系統(tǒng)對擴展開放,對修改封閉欲间,通過擴展達到增強其功能的目的楚里,對于涉及到多個產(chǎn)品族與多個產(chǎn)品等級結(jié)構(gòu)的系統(tǒng),其功能增強包括兩方面:

  • 增加產(chǎn)品族:對于增加新的產(chǎn)品族猎贴,抽象工廠模式很好地支持了“開閉原則”班缎,只需要增加具體產(chǎn)品并對應增加一個新的具體工廠,對已有代碼無須做任何修改她渴。
  • 加新的產(chǎn)品等級結(jié)構(gòu):對于增加新的產(chǎn)品等級結(jié)構(gòu)达址,需要修改所有的工廠角色,包括抽象工廠類趁耗,在所有的工廠類中都需要增加生產(chǎn)新產(chǎn)品的方法沉唠,違背了“開閉原則”。

正因為抽象工廠模式存在“開閉原則”的傾斜性苛败,它以一種傾斜的方式來滿足“開閉原則”满葛,為增加新產(chǎn)品族提供方便,但不能為增加新產(chǎn)品結(jié)構(gòu)提供這樣的方便罢屈,因此要求設(shè)計人員在設(shè)計之初就能夠全面考慮嘀韧,不會在設(shè)計完成之后向系統(tǒng)中增加新的產(chǎn)品等級結(jié)構(gòu),也不會刪除已有的產(chǎn)品等級結(jié)構(gòu)缠捌,否則將會導致系統(tǒng)出現(xiàn)較大的修改锄贷,為后續(xù)維護工作帶來諸多麻煩。

抽象工廠模式總結(jié)

  • 優(yōu)點
    • 抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什么被創(chuàng)建谊却。由于這種隔離柔昼,更換一個具體工廠就變得相對容易,所有的具體工廠都實現(xiàn)了抽象工廠中定義的那些公共接口炎辨,因此只需改變具體工廠的實例捕透,就可以在某種程度上改變整個軟件系統(tǒng)的行為。
    • 當一個產(chǎn)品族中的多個對象被設(shè)計成一起工作時蹦魔,它能夠保證客戶端始終只使用同一個產(chǎn)品族中的對象激率。
    • 增加新的產(chǎn)品族很方便,無須修改已有系統(tǒng)勿决,符合“開閉原則”乒躺。
  • 缺點
    • 增加新的產(chǎn)品等級結(jié)構(gòu)麻煩,需要對原有系統(tǒng)進行較大的修改低缩,甚至需要修改抽象層代碼嘉冒,這顯然會帶來較大的不便,違背了“開閉原則”咆繁。
  • 適用場景
    • 一個系統(tǒng)不應當依賴于產(chǎn)品類實例如何被創(chuàng)建讳推、組合和表達的細節(jié),這對于所有類型的工廠模式都是很重要的玩般,用戶無須關(guān)心對象的創(chuàng)建過程银觅,將對象的創(chuàng)建和使用解耦。
    • 系統(tǒng)中有多于一個的產(chǎn)品族坏为,而每次只使用其中某一產(chǎn)品族究驴。可以通過配置文件等方式來使得用戶可以動態(tài)改變產(chǎn)品族匀伏,也可以很方便地增加新的產(chǎn)品族洒忧。
    • 屬于同一個產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計中體現(xiàn)出來够颠。同一個產(chǎn)品族中的產(chǎn)品可以是沒有任何關(guān)系的對象熙侍,但是它們都具有一些共同的約束,如同一操作系統(tǒng)下的按鈕和文本框履磨,按鈕與文本框之間沒有直接關(guān)系蛉抓,但它們都是屬于某一操作系統(tǒng)的,此時具有一個共同的約束條件:操作系統(tǒng)的類型剃诅。
    • 產(chǎn)品等級結(jié)構(gòu)穩(wěn)定巷送,設(shè)計完成之后,不會向系統(tǒng)中增加新的產(chǎn)品等級結(jié)構(gòu)或者刪除已有的產(chǎn)品等級結(jié)構(gòu)综苔。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惩系,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子如筛,更是在濱河造成了極大的恐慌堡牡,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杨刨,死亡現(xiàn)場離奇詭異晤柄,居然都是意外死亡,警方通過查閱死者的電腦和手機妖胀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門芥颈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赚抡,你說我怎么就攤上這事爬坑。” “怎么了涂臣?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵盾计,是天一觀的道長。 經(jīng)常有香客問我赁遗,道長署辉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任岩四,我火速辦了婚禮哭尝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剖煌。我一直安慰自己材鹦,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布末捣。 她就那樣靜靜地躺著侠姑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪箩做。 梳的紋絲不亂的頭發(fā)上莽红,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音邦邦,去河邊找鬼安吁。 笑死,一個胖子當著我的面吹牛燃辖,可吹牛的內(nèi)容都是我干的鬼店。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼黔龟,長吁一口氣:“原來是場噩夢啊……” “哼妇智!你這毒婦竟也來了滥玷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤巍棱,失蹤者是張志新(化名)和其女友劉穎惑畴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航徙,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡如贷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了到踏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杠袱。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖窝稿,靈堂內(nèi)的尸體忽然破棺而出楣富,到底是詐尸還是另有隱情,我是刑警寧澤伴榔,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布厢呵,位于F島的核電站腹殿,受9級特大地震影響漏麦,放射性物質(zhì)發(fā)生泄漏游添。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一秉馏、第九天 我趴在偏房一處隱蔽的房頂上張望耙旦。 院中可真熱鬧,春花似錦萝究、人聲如沸免都。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绕娘。三九已至,卻和暖如春栽连,著一層夾襖步出監(jiān)牢的瞬間险领,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工秒紧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绢陌,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓熔恢,卻偏偏與公主長得像脐湾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子叙淌,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容