1. 程式人生 > >簡單工廠模式、工廠模式和抽象工廠模式區別及優缺點

簡單工廠模式、工廠模式和抽象工廠模式區別及優缺點

各位小夥伴好,今天給大家主要介紹一下簡單工廠模式、工廠模式和抽象工廠模式的區別及各自的優缺點。

(本文實現語言為Python3)

【前言】

眾所周知今天所講的內容是設計模式的一類;對於設計模式這個概念,我想首先請大家問問自己:1、什麼是設計模式 2、我們為什麼要了解並學習設計模式?

從我上學的時候我相信大家跟我一樣也接觸過設計模式的課程,當時可能懵懵懂懂只是知其然,當時還會想明明可以直接寫出來為什麼要搞成這樣的形式,我就算學會了它到底什麼時候能用呢?一系列的問題...Emm算了到時候再想想(lazy)。隨著實踐的不斷增多,現在我想可以對這些問題有個初步的回答了:

  1、在我看來,設計模式外在看是經過前人不斷實踐總結出的針對某些指定場景極其好用的一種程式碼結構設計模板;內在看其實是一種設計思想(即為什麼他們會這麼想,這樣想較之其他方法有什麼好處)。當我們真正的理解設計思想的時候,就可能會在面對問題和場景時自然而然的靈活運用到多種設計模式,而不是單一的刻板結構。

  2、在工程化的開發中,需求往往是會不斷變化的,這也是讓很多開發人員及其煩躁的地方,所以才會有開發與產品的親密關係。設計模式就是為了抵禦外部需求變化產生的。設計模式應符合開閉原則(類、模組和函式等應該對擴充套件開放,對修改關閉。)一個好的設計在之後的開發中,包括髮生重大需求變化的時候,往往程式碼只需要進行簡單重構去進行適配,而不是通過打補丁的方式去堆砌,也很容易避免破窗效應,充分的發揮了靈活的擴充套件和適配,大大增強了維護性。

  綜上所述,我們瞭解並學習設計模式,可以使我們的程式碼變得更加健壯、結構清晰,可以從容、靈活的適配需求變更(可複用、可擴充套件、可維護、夠靈活)

【正文】

首先,這三種模式解決的問題是例項化物件的問題;那麼為什麼不直接例項化而用這樣的工廠形式去例項化物件呢?

因為【待例項化物件太多(子類多且變動、呼叫頻繁)或者例項化物件的過程、準備比較複雜】,直接例項化意味著每次都用重複的去執行例項化這個操作,如果有很多待例項化的操作,那麼就要重複執行很多次,更不要說萬一在例項化之前還要執行一堆配置項的初始化。所以用工廠模式去代替直接例項化物件是為了可複用,並且可以實現模組間的解耦。

如果是簡單的例項化是沒有必要引入工廠模式的,這樣還會增加系統的複雜度。

簡單工廠模式和抽象工廠模式都是派生於工廠模式的,屬於一類;在對問題的解決上你可以理解成三種方案,解決某類問題用某種方案最好;但在複雜程度上來說算是層層遞進的。我這裡就按實現的簡單程度升序說明。(這裡我準備用例項化手機物件舉例說明)

一、簡單工廠模式(又叫靜態工廠模式)

  顧名思義,這是對工廠模式的一種“簡單”實現,也是理解起來比較簡單的。它的本質是通過傳入不同的引數來實現多型,達到例項化不同物件的目的。

       

    class MobileFactory:
        """ 簡單工廠模式 生產手機的工廠"""

        def get_mobile(self, name):
            if name == 'huawei':
                return HuaWei()
            elif name == 'iphone':
                return Iphone()


    class MobliePhone:
        pass


    class HuaWei(MobliePhone):
        pass


    class Iphone(MobliePhone):
        pass


    hw = MobileFactory().get_mobile('huawei')
    ip = MobileFactory().get_mobile('iphone')
    print(hw)  # <__main__.HuaWei object at 0x00000000021F9160>
    print(ip)  # <__main__.Iphone object at 0x00000000022AD0F0>

二、工廠模式(又稱為建立模式)

       是對簡單工廠模式多了一層抽象,將例項化某一類物件具體細分給對應的工廠,而不是在一個工廠裡通過依賴引數

  

    class MobileFactory:
        """ 工廠模式 生產手機的工廠"""

        def get_mobile(self):
            pass


    class HWFactory(MobileFactory):
        def get_mobile(self):
            return 'get a HW phone'


    class IphoneFactory(MobileFactory):
        def get_mobile(self):
            return 'get an iphone'


    hw, ip = HWFactory(), IphoneFactory()
    print(hw.get_mobile())  # get a HW phone
    print(ip.get_mobile())  # get an iphone

三、抽象工廠模式

  是對工廠模式又進行了一層抽象,不單單是像工廠模式只生成一類產品,而是一系列產品,並且可以像零件一樣靈活配置給各工廠。

  

"""
    抽象工廠模式
    【假設】華為和蘋果都生產手機和螢幕,而我家只生產螢幕
    """


    # 有螢幕和手機兩款產品
    class Screen:
        def __init__(self):
            print('i am a screen')


    class Mobile:
        def __init__(self):
            print('i am a mobile')


    # 三個廠家各自的螢幕和手機
    class HWScreen(Screen):
        def __init__(self):
            print('HW screen')


    class IphoneScreen(Screen):
        def __init__(self):
            print('Iphone screen')


    class MyScreen(Screen):
        def __init__(self):
            print('My screen')


    class HWMobile(Mobile):
        def __init__(self):
            print('HW Mobile')


    class IphoneMobile(Mobile):
        def __init__(self):
            print('Iphone Mobile')


    # 生產工廠
    class Factory:
        def get_screen(self):
            pass

        def get_mobile(self):
            pass


    # 各家自己的工廠
    class HWFactory(Factory):
        def get_mobile(self):
            return HWMobile()

        def get_screen(self):
            return HWScreen()


    class IphoneFactory(Factory):
        def get_screen(self):
            return IphoneScreen()

        def get_mobile(self):
            return IphoneMobile()


    class MyFactory(Factory):
        def get_screen(self):
            return MyScreen()


    # 我要生產東西咯
    hw, ip, my = HWFactory(), IphoneFactory(), MyFactory()
    hw.get_mobile()  # HW Mobile
    hw.get_screen()  # HW screen
    ip.get_mobile()  # Iphone Mobile
    ip.get_screen()  # Iphone screen
    my.get_screen()  # My screen

 

【總結與說明】

  首先說明由於Python面向物件比較徹底,天然的實現了多型,所以例子看起來可能不如靜態語言Java更加清晰,但是可以通過例子理解要傳遞表達的設計思想。

       看完上述三段程式碼示例後,相信大家可能有的人會豁然開朗,有的人可能只是剛剛梳理好思路。在這裡我希望大家先問問自己三個模式的優缺點,並且帶著對它們的疑問進行程式碼實踐,這樣才會對理解和感悟有更深刻的認識。

       一、簡單工廠模式 【優點】:1、客戶端建立物件時只需要記住特定的引數,而不需要記住複雜的類名,也不用關注實現的過程。(實現了封裝和部分解耦)

                                                       2、建立物件不需要單獨例項化,而是通過工廠類直接獲取示例(實現複用)

                                     【缺點】:1、例項化物件的邏輯全部封裝在一個工廠類裡,每次需求變化都要單獨修改工廠類(違反了開閉原則),而且出了異常可能沒法正常工作。

                                                       2、不方便擴充套件子類

          【應用場景】:適合業務簡單或者產品較少的情況

       二、工廠模式        【優點】:1、在簡單工廠的基礎上遵循了開閉原則,又進行了解耦,工廠類分為具體的工廠類

                                    【缺點】:1、每增加一個工廠,就要額外開發一個工廠

                                    【應用場景】:正文中符合工廠模式的情況,多由於解耦

       三、抽象工廠模式   【優點】:1、正是由於複雜的抽象關聯關係使得在類的內部對一系列產品組的管理很方便

                                       【缺點】:1、擴充套件很費力,每次要修改很多類。

                                       【應用場景】:待建立的物件是一系列相互關聯或相互依賴的產品