設計模式——把類作為引數的抽象工廠模式

TechFlow2019發表於2021-03-09

今天給大家介紹一個非常簡單的設計模式,一學就會,非常好用。

這個模式叫做抽象工廠模式,大家可能對工廠模式比較熟悉,在工廠模式當中封裝了例項的建立邏輯。主要的用途一般是將一些複雜的類的建立過程整合在一起,通過引數控制,這樣使用者可以較簡單地獲得例項。

抽象工廠

抽象工廠模式和工廠模式類似,只不過更加抽象了一層。在建立例項的時候,不是通過引數來控制,而是直接傳入想要建立的類。這一點其實也是Python的特性,一切皆是物件,一切皆可傳參,類本身也是一個物件,類也是可以傳參的。所以我們可以把一個類直接傳入工廠,工廠通過類來建立例項。

我們來用程式碼簡單演示一下:

class AbstractFactory:
    def __init__(self, cls):
        self.cls = cls
        
    def build(self, *args, **kw):
        return self.cls(*args, **kw)

這段程式碼大家都能看懂,但是這其實也不能完全叫做抽象工廠,因為體現不出來抽象。這裡的抽象主要是把工廠當做了一個更高階的抽象類,有點像是抽象類的反向使用。

我們一般使用抽象類都是這樣:

import abc

class AbstractClass:
    def __init__(self):
        pass
    
    @abc.abstractmethod
    def run(self, *args, **kw):
        pass

然後它的派生類再去實現抽象類當中定義的抽象方法,而這裡的順序則是反的。父類當中的邏輯其實也是定好的,只是它在具體執行的時候是呼叫傳入的子類例項實現的。

為了更好說明,我們來看一個例子吧:

class PetCollection(object):

    def __init__(self, animal):
        self.pet_generator = animal
        self.pet = self.pet_generator()
    
    def speak(self):
        self.pet.speak()

    def show_pet(self):
        pet = self.pet
        print('Pet\'s name is {}'.format(pet))
        print('It says: {}!'.format(pet.speak()))


class Dog(object):
    def speak(self):
        return 'woof'

    def __str__(self):
        return 'dog'


class Cat(object):
    def speak(self):
        return 'meow'

    def __str__(self):
        return 'cat'

if __name__ == '__main__':
    pet = PetCollection(Dog)
    pet.show_pet()

在這個例子當中,Dog和Cat是子類,PetCollection是父類。我們可以發現在父類當中也實現了speak這個方法,但是它是呼叫子類的speak實現的。也就是說凡是擁有speak這個類的子類都可以用來建立PetCollection,這個PetCollection相當於一個抽象的通用類,這樣我們在使用的時候可以用它來整合很多邏輯,簡化操作。

我第一次看這個設計模式的時候,覺得普普通通,不過是把類當做引數而已。但是之後又看了一次,又有了新的理解,這不也是抽象類的反向使用嗎?其實程式碼的核心就只有邏輯,所謂的設計模式也不過是前人總結出的經驗而已。真正有價值的並不是這個模式當中的程式碼怎麼寫,而是核心的邏輯,這些融會貫通了,以後也不難設計出我們自己的模式來。

今天的文章就到這裡,衷心祝願大家每天都有所收穫。如果還喜歡今天的內容的話,不要忘了三連。

原文發表於公眾號TechFlow,求個關注

{{uploading-image-465998.png(uploading...)}}

相關文章