抽象工廠模式 —— Python 描述

z正小歪發表於2016-12-17

抽象工廠模式的實質是提供「介面」,子類通過實現這些介面來定義具體的操作。

這些通用的介面如同協議一樣,協議本身定義了一系列方法去描述某個類,子類通過實現這些方法從而實現了該類。

子類中不用關心這個類該是什麼樣子的,這些都有抽象類去定義,這就區分設計類和實現類兩個過程,實現過程的解耦。

程式碼描述

描述一個這樣的過程:有一個 GUIFactory,GUI 有 Mac 和 Windows 兩種風格,現在需要建立兩種不同風格的 Button,顯示在 Application 中。

class GUIFactory(object):
    def __init__(self):
        self.screen = None

    def set_screen(self):
        raise NotImplementedError

    def get_size_from_screen(self, screen):
        if self.screen == 'retina':
            return '2560 x 1600'

        elif self.screen == 'full_hd':
            return '1920 x 1080'複製程式碼

定義 Mac 和 Windows 兩種風格的 GUI。

class MacGUIFactory(GUIFactory):
    def __init__(self):
        super(MacGUIFactory, self).__init__()

    def set_screen(self):
        self.screen = 'retina' 

    def set_attributes(*args, **kwargs):
        raise NotImplementedError


class WinGUIFactory(GUIFactory):
    def __init__(self):
        super(WinGUIFactory, self).__init__()

    def set_screen(self):
        self.screen = 'full_hd' 

    def set_attributes(*args, **kwargs):
        raise NotImplementedError複製程式碼

所有 GUI 都需要設定螢幕的型別,否則在呼叫時候會丟擲 NotImplementedError 的異常,抽象了設定 Button 屬性的方法,讓子類必須實現。

class MacButton(MacGUIFactory):
    def __init__(self):
        super(MacButton, self).__init__()
        self.set_screen()
        self.color = 'black'

    def set_attributes(self, *args, **kwargs):
        if 'color' in kwargs:
            self.color = kwargs.get('color') 

    def verbose(self):
        size = self.get_size_from_screen(self.screen) 
        print('''i am the {color} button of mac on {size} screen'''.format(
            color=self.color, size=size))


class WinButton(WinGUIFactory):
    def __init__(self):
        super(WinButton, self).__init__()
        self.set_screen()
        self.color = 'black'

    def set_attributes(self, *args, **kwargs):
        if 'color' in kwargs:
            self.color = kwargs.get('color') 

    def verbose(self):
        size = self.get_size_from_screen(self.screen) 
        print('''i am the {color} button of win on {size} screen'''.format(
            color=self.color, size=size))複製程式碼

實現建立不同平臺 Button 的方法, 需要根據螢幕的大小建立不同尺寸的 Button,才能有更好的顯示效果。

這樣就分別實現了兩種不同 Button 的建立,還可以封裝一個 Button 類來管理這兩個不同的 Button。

class Button(object):
    @staticmethod
    def create(platform, *args, **kwargs):
        if platform.lower() == 'mac':
            return MacButton()        
        elif platform.lower() == 'win':
            return WinButton()複製程式碼

建立兩個不同平臺的 Button,並且設定顏色屬性

win_button = Button.create('win')
mac_button = Button.create('mac')

win_button.set_attributes(color='red')
mac_button.set_attributes(color='blue')

win_button.verbose()
# >> i am the red button of win on 1920 x 1080 screen
mac_button.verbose()
# >> i am the blue button of mac on 2560 x 1600 screen複製程式碼

適用範圍

以下情況可以適用抽象工廠模式:

  • 獨立於系統的模組
  • 系統中各大類的模組
  • 需要強調設計和實現分離的時候
  • 只想顯示介面並不想實現的時候

優缺點

優點:

  • 具體產品從客戶程式碼中被分離出來
  • 容易改變產品的系列
  • 將一個系列的產品族統一到一起建立

缺點:

  • 在產品族中擴充套件新的產品是很困難的,它需要修改抽象工廠的介面

Reference

相關文章