工廠的意義
模擬現實工廠,通過“工廠”獲取“產品”,用戶只需通過固定的接口獲得一個對象的實例。降低了維護的複雜性。
下面我將對無工廠方式,簡單工廠方式,工廠方式,抽象工廠方式進行對比與分析。
無工廠
代碼祭天:
#encoding=utf-8
class IPhone(object):
#蘋果
def __repr__(self):
return "IPhone"
class Huawei(object):
# 華爲
def __repr__(self):
return "Huawei"
#encoding=utf-8
class IMAC(object):
#蘋果
def __repr__(self):
return "IMAC"
class HuaweiMAC(object):
# 華爲
def __repr__(self):
return "HuaweiMAC"
if __name__ == '__main__':
print IPhone()
print Huawei()
print IMAC()
print HuaweiMAC
假設我麼有四個產品分別是:
(蘋果手機,IPhone),(蘋果電腦,IMAC),(華爲手機,Huawei),(華爲電腦,HuaweiMAC)四個類
在主函數中實例化四個類對象
運行主函數結果:
IPhone
IMAC
Huawei
HuaweiMAC
缺點 | 但現實中,你可能會面對很多產品,而且每個產品的構造參數還不一樣,這樣在創建實例時會遇到麻煩。 |
優點 | 簡單易懂,初學者適用 |
簡單工廠
代碼祭天:
from noFactory import IPhone, Huawei
class SimplePhoneFactory(object):
@staticmethod
def get_phone(name):
if name == 'iphone':
return IPhone()
elif name == 'huawei':
return Huawei()
if __name__ == '__main__':
print SimplePhoneFactory.get_phone('iphone')
print SimplePhoneFactory.get_phone('huawei')
運行主函數結果:
IPhone
Huawei
構造一個“簡單工廠”把所有實例化的過程封裝在裏面。需要什麼直接調工廠裏的方法。
缺點 | 但在實際使用工廠的過程中,我們會發現新問題:如果我們要新增一個“產品”就需要修改getphone()方法違背了軟件設計中的開閉原則即在擴展新的類時,儘量不要修改原有代碼。 |
優點 | 簡單易懂,適用於需創建的對象較少,不會造成工廠方法中的業務邏輯太過複雜的情況下,而且用戶只關心哪種類型的實例被創建, |
工廠方法
代碼祭天:
# coding=utf-8
import abc
# 工廠方法
from noFactory import IPhone, Huawei
class AbstractFactory(object):
# 抽象的工廠類
__metaclass__ = abc.ABCMeta
# python不同於java沒有abstract抽象類關鍵字通過加載abc實現抽象方法
@abc.abstractmethod
def get_phone(self):
pass
# 蘋果工廠
class IPhoneFactory(AbstractFactory):
def get_phone(self):
return IPhone()
# 華爲工廠
class HuaweiFactory(AbstractFactory):
def get_phone(self):
return Huawei()
if __name__ == '__main__':
iphone = IPhoneFactory().get_phone()
huawei = HuaweiFactory().get_phone()
print iphone
print huawei
運行主函數結果:
IPhone
Huawei
我們在簡單工廠的基礎上抽象成不同的工廠,每個工廠對應生成自己的產品,這就是工廠方法。
缺點 | 複雜度提升,代碼的可讀性降低,仍不能完全解決複雜場景 |
優點 | 耦合性降低,每個工廠負責生產自己的產品也避免了我們在新增產品時需要修改工廠的代碼,而只要增加相應的工廠即可 |
抽象工廠方法
代碼祭天:
# coding=utf-8
import abc
# 工廠方法
from noFactory import IPhone, Huawei, IMAC, HuaweiMAC
class AbstractFactory(object):
# 抽象的工廠類
__metaclass__ = abc.ABCMeta
# python不同於java沒有abstract抽象類關鍵字通過加載abc實現抽象方法
@abc.abstractmethod
def get_phone(self):
pass
@abc.abstractmethod
def get_computer(self):
pass
# 蘋果工廠
class IPhoneFactory(AbstractFactory):
def get_phone(self):
return IPhone()
def get_computer(self):
return IMAC()
# 華爲工廠·
class HuaweiFactory(AbstractFactory):
def get_phone(self):
return Huawei()
def get_computer(self):
return HuaweiMAC()
if __name__ == '__main__':
print IPhoneFactory().get_phone()
print IPhoneFactory().get_computer()
print HuaweiFactory().get_phone()
print HuaweiFactory().get_computer()
運行主函數結果:
IPhone
IMAC
Huawei
HuaweiMAC
當產品增多業務複雜時,例如工廠不僅生產手機還要生產電腦時面對這種業務場景,就需要使用抽象工廠方法
缺點 | 複雜度提升,代碼的可讀性降低 |
優點 | 適用於複雜的業務場景 |