設(shè)計(jì)模式——把類(lèi)作為參數(shù)的抽象工廠模式
今天給大家介紹一個(gè)非常簡(jiǎn)單的設(shè)計(jì)模式,一學(xué)就會(huì),非常好用。
這個(gè)模式叫做抽象工廠模式,大家可能對(duì)工廠模式比較熟悉,在工廠模式當(dāng)中封裝了實(shí)例的創(chuàng)建邏輯。主要的用途一般是將一些復(fù)雜的類(lèi)的創(chuàng)建過(guò)程整合在一起,通過(guò)參數(shù)控制,這樣使用者可以較簡(jiǎn)單地獲得實(shí)例。
抽象工廠
抽象工廠模式和工廠模式類(lèi)似,只不過(guò)更加抽象了一層。在創(chuàng)建實(shí)例的時(shí)候,不是通過(guò)參數(shù)來(lái)控制,而是直接傳入想要?jiǎng)?chuàng)建的類(lèi)。這一點(diǎn)其實(shí)也是Python的特性,一切皆是對(duì)象,一切皆可傳參,類(lèi)本身也是一個(gè)對(duì)象,類(lèi)也是可以傳參的。所以我們可以把一個(gè)類(lèi)直接傳入工廠,工廠通過(guò)類(lèi)來(lái)創(chuàng)建實(shí)例。
我們來(lái)用代碼簡(jiǎn)單演示一下:
- class AbstractFactory:
- def __init__(self, cls):
- self.cls = cls
- def build(self, *args, **kw):
- return self.cls(*args, **kw)
這段代碼大家都能看懂,但是這其實(shí)也不能完全叫做抽象工廠,因?yàn)轶w現(xiàn)不出來(lái)抽象。這里的抽象主要是把工廠當(dāng)做了一個(gè)更高階的抽象類(lèi),有點(diǎn)像是抽象類(lèi)的反向使用。
我們一般使用抽象類(lèi)都是這樣:
- import abc
- class AbstractClass:
- def __init__(self):
- pass
- @abc.abstractmethod
- def run(self, *args, **kw):
- pass
然后它的派生類(lèi)再去實(shí)現(xiàn)抽象類(lèi)當(dāng)中定義的抽象方法,而這里的順序則是反的。父類(lèi)當(dāng)中的邏輯其實(shí)也是定好的,只是它在具體執(zhí)行的時(shí)候是調(diào)用傳入的子類(lèi)實(shí)例實(shí)現(xiàn)的。
為了更好說(shuō)明,我們來(lái)看一個(gè)例子吧:
- 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()
在這個(gè)例子當(dāng)中,Dog和Cat是子類(lèi),PetCollection是父類(lèi)。我們可以發(fā)現(xiàn)在父類(lèi)當(dāng)中也實(shí)現(xiàn)了speak這個(gè)方法,但是它是調(diào)用子類(lèi)的speak實(shí)現(xiàn)的。也就是說(shuō)凡是擁有speak這個(gè)類(lèi)的子類(lèi)都可以用來(lái)創(chuàng)建PetCollection,這個(gè)PetCollection相當(dāng)于一個(gè)抽象的通用類(lèi),這樣我們?cè)谑褂玫臅r(shí)候可以用它來(lái)集成很多邏輯,簡(jiǎn)化操作。
我第一次看這個(gè)設(shè)計(jì)模式的時(shí)候,覺(jué)得普普通通,不過(guò)是把類(lèi)當(dāng)做參數(shù)而已。但是之后又看了一次,又有了新的理解,這不也是抽象類(lèi)的反向使用嗎?其實(shí)代碼的核心就只有邏輯,所謂的設(shè)計(jì)模式也不過(guò)是前人總結(jié)出的經(jīng)驗(yàn)而已。真正有價(jià)值的并不是這個(gè)模式當(dāng)中的代碼怎么寫(xiě),而是核心的邏輯,這些融會(huì)貫通了,以后也不難設(shè)計(jì)出我們自己的模式來(lái)。
本文轉(zhuǎn)載自微信公眾號(hào)「TechFlow」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系TechFlow公眾號(hào)。