除非需求非常明確,通常一開(kāi)始無(wú)法確定哪些地方需要通過(guò)設(shè)計(jì)模式來(lái)優(yōu)化代碼的組織,因此通常的做法是先根據(jù)當(dāng)前需求編寫(xiě)簡(jiǎn)單實(shí)現(xiàn),等到變化發(fā)生時(shí)立即采取行動(dòng),分析、抽象、隔離這些變化。抽象不是越早越好,應(yīng)當(dāng)拒絕不成熟的抽象。**
工廠方法模式:定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類(lèi)決定實(shí)例化哪一個(gè)類(lèi)。工廠方法使一個(gè)類(lèi)的實(shí)例化延遲到其子類(lèi)。
基本思想
- 定義一個(gè)抽象的工廠接口類(lèi)
- 定義一個(gè)抽象的產(chǎn)品接口類(lèi)
- 根據(jù)需要從產(chǎn)品接口派生產(chǎn)品子類(lèi)
- 對(duì)于每一個(gè)產(chǎn)品子類(lèi),從工廠接口派生工廠子類(lèi),負(fù)責(zé)該產(chǎn)品的創(chuàng)建
- 客戶(hù)端根據(jù)實(shí)際需要,調(diào)用工廠子類(lèi),創(chuàng)建所需要的產(chǎn)品。
代碼框架
拿簡(jiǎn)單工廠模式中的動(dòng)物工廠來(lái)舉例說(shuō)明
class Animal(object):
def eat(self, food):
raise NotImplementedError()
class Dog(Animal):
def eat(self, food):
print '狗吃', food
class Cat(Animal):
def eat(self, food):
print '貓吃', food
class AnimalFactory(object):
def create_animal(self):
raise NotImplementedError()
class DogFactory(Animal):
def create_animal(self):
return Dog()
class CatFactory(AnimalFactory):
def create_animal(self):
return Cat()
def client():
animal_factory = DogFactory()
animal = animal_factory.create_animal()
animal.eat('肉骨頭')
animal_factory = CatFactory()
animal = animal_factory.create_animal()
animal.eat('魚(yú)骨頭')
下面是簡(jiǎn)單工廠模式的實(shí)現(xiàn):
class Animal(object):
def eat(self, food):
raise NotImplementedError()
class Dog(Animal):
def eat(self, food):
print '狗吃', food
class Cat(Animal):
def eat(self, food):
print '貓吃', food
def create_animal(name):
if name == 'dog':
return Dog()
elif name == 'cat':
return Cat()
def client():
animal = create_animal('dog')
animal.eat('肉骨頭')
animal = create_animal('cat')
animal.eat('魚(yú)骨頭')
看起來(lái)工廠方法模式要復(fù)雜很多啊,也沒(méi)覺(jué)得比簡(jiǎn)單工廠模式有什么好處,為什么還要用工廠方法模式呢?
簡(jiǎn)單工廠模式的優(yōu)點(diǎn)很明顯,工廠函數(shù)封裝了邏輯判斷,客戶(hù)端使用負(fù)擔(dān)要小很多。相應(yīng)的問(wèn)題也很明顯,要增加新的產(chǎn)品類(lèi)型,就需要修改工廠函數(shù),這違背了開(kāi)閉原則。
但是工廠方法模式似乎繞了一圈又回到原始時(shí)代了,下面寫(xiě)不就行了嗎,何必外面套一層Factory:
class Animal(object):
def eat(self, food):
raise NotImplementedError()
class Dog(Animal):
def eat(self, food):
print '狗吃', food
class Cat(Animal):
def eat(self, food):
print '貓吃', food
def client():
dog = Dog()
dog.eat('肉骨頭')
cat = Cat()
cat.eat('魚(yú)骨頭')
工廠方法模式,對(duì)于需要做強(qiáng)類(lèi)型檢查的語(yǔ)言比如Java、C++等在組織代碼時(shí)是有好處的。對(duì)于Python這種動(dòng)態(tài)語(yǔ)言來(lái)說(shuō),感覺(jué)體現(xiàn)不出太多價(jià)值,或許我還沒(méi)有理解工廠方法模式的真諦。
原文地址:http://www.isware.cn/python-design-pattern/02-factory-method/