建立型模式:工廠方法模式、抽象工廠模式、建立者模式、原型模式、單例模式。
python
不直接向客戶端暴露對象建立的實現細節,而是經過一個工廠類來負責建立產品類的實例。該模式不屬於23種設計模式之一。shell
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # abstract class @abstractmethod def pay(self, money): pass class Alipay(Payment): def __init__(self, use_huabei=False): self.use_huabei = use_huabei def pay(self, money): if self.use_huabei: print('支付寶支付%d元' % money) else: print('支付寶餘額支付%d元。' % money) class WechatPay(Payment): def pay(self, money): print("微信支付%d元" % money) class PaymentFactory: # 工廠類:生產支付對象 def create_payment(self, method): if method == 'alipay': return Alipay() elif method == 'wechat': return WechatPay() elif method == 'huabei': return Alipay(use_huabei=True) else: raise TypeError("No such payment named %s" % method) pf = PaymentFactory() # p = pf.create_payment('alipay') p = pf.create_payment('huabei') # 隱藏了類的內部實現,無需瞭解代碼邏輯 p.pay(100)
Payment是抽象類,是爲了讓產品有一樣的表現,能夠一樣的對外使用。若是要增長新的支付,好比銀行支付,只要添加新的產品類便可。數據庫
角色:設計模式
優勢:微信
缺點:函數
定義一個用於建立對象的接口(工廠接口),讓子類決定實例化哪個產品類。微信支付
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # 產品接口 # abstract class @abstractmethod def pay(self, money): pass class Alipay(Payment): # 具體產品 def __init__(self, use_huabei=False): self.use_huabei = use_huabei def pay(self, money): if self.use_huabei: print('支付寶支付%d元' % money) else: print('支付寶餘額支付%d元。' % money) class WechatPay(Payment): def pay(self, money): print("微信支付%d元" % money) class BankPay(Payment): # 建立一個新產品 def pay(self, money): print("銀行卡支付%d元" % money) class PaymentFactory(metaclass=ABCMeta): # 工廠類接口 @abstractmethod def create_payment(self): pass class AlipayFactory(PaymentFactory): # 具體工廠類 def create_payment(self): return Alipay() class WechatPayFactory(PaymentFactory): def create_payment(self): return WechatPay() class HuabeiFactory(PaymentFactory): def create_payment(self): return Alipay(use_huabei=True) class BankPayFactory(PaymentFactory): # 建立新產品對應的工廠 def create_payment(self): return BankPay() pf = HuabeiFactory() # 建立工廠 p = pf.create_payment() p.pay(100)
角色:ui
優勢:spa
缺點:操作系統
定義一個工廠類接口,讓工廠子類來建立一系列相關或相互依賴的對象。
例:生產一部手機,須要手機殼、CPU、操做系統三類對象進行組裝,其中每類對象都有不一樣的種類。對每一個具體工廠,分別生產一部手機所須要的三個對象。
from abc import abstractmethod, ABCMeta # ------抽象產品------ class PhoneShell(metaclass=ABCMeta): # 手機殼 @abstractmethod def show_shell(self): pass class CPU(metaclass=ABCMeta): # cpu @abstractmethod def show_cpu(self): pass class OS(metaclass=ABCMeta): # 系統 @abstractmethod def show_os(self): pass # ------抽象工廠------ class PhoneFactory(metaclass=ABCMeta): # 每一個工廠都生產一套產品 @abstractmethod def make_shell(self): pass @abstractmethod def make_cpu(self): pass @abstractmethod def make_os(self): pass # ------具體產品------ class SmallShell(PhoneShell): def show_shell(self): print("普通手機小手機殼") class BigShell(PhoneShell): def show_shell(self): print("普通手機大手機殼") class AppleShell(PhoneShell): def show_shell(self): print("蘋果手機殼") class SnapDragonCPU(CPU): def show_cpu(self): print("驍龍CPU") class MediaTekCPU(CPU): def show_cpu(self): print("聯發科CPU") class AppleCPU(CPU): def show_cpu(self): print("蘋果CPU") class Android(OS): def show_os(self): print("Android系統") class IOS(OS): def show_os(self): print("iOS系統") # ------具體工廠------ class MiFactory(PhoneFactory): # 小米工廠 def make_cpu(self): return SnapDragonCPU() def make_os(self): return Android() def make_shell(self): return BigShell() class HuaweiFactory(PhoneFactory): # 華爲工廠 def make_cpu(self): return MediaTekCPU() def make_os(self): return Android() def make_shell(self): return SmallShell() class IPhoneFactory(PhoneFactory): # 蘋果工廠,一套組件還作了限制 def make_cpu(self): return AppleCPU() # 蘋果cpu def make_os(self): return IOS() # 蘋果系統 def make_shell(self): return AppleShell() # 蘋果手機殼 # ------客戶端------ class Phone: # 手機 def __init__(self, cpu, os, shell): self.cpu = cpu self.os = os self.shell = shell def show_info(self): print("手機信息:") self.cpu.show_cpu() self.os.show_os() self.shell.show_shell() def make_phone(factory): cpu = factory.make_cpu() os = factory.make_os() shell = factory.make_shell() return Phone(cpu, os, shell) # 生成手機對象 p1 = make_phone(IPhoneFactory()) # 生成一個蘋果手機對象 p1.show_info()
相比工廠方法模式,抽象工廠模式中每一個具體工廠都生產一套產品。
角色:
優勢:
缺點:
將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
from abc import ABCMeta, abstractmethod class Player: # 產品:遊戲角色 def __init__(self, face=None, body=None, arm=None, leg=None): # 傳入初始化參數 self.face = face self.body = body self.arm = arm self.leg = leg def __str__(self): return "%s, %s, %s, %s" % (self.face, self.body, self.arm, self.leg) class PlayerBuilder(metaclass=ABCMeta): # 抽象建造者:抽象類做爲接口 @abstractmethod def build_face(self): pass @abstractmethod def build_body(self): pass @abstractmethod def build_arm(self): pass @abstractmethod def build_leg(self): pass class SexyGirlBuilder(PlayerBuilder): # 具體建立者:女性角色 def __init__(self): self.player = Player() # 玩家 def build_face(self): self.player.face = "漂亮臉蛋" def build_body(self): self.player.body = "苗條" def build_arm(self): self.player.arm = "漂亮胳膊" def build_leg(self): self.player.leg = "大長腿" class Monster(PlayerBuilder): # 具體建立者:怪物 def __init__(self): self.player = Player() def build_face(self): self.player.face = "怪獸臉" # 被隱藏的產品內部結構,也是表示代碼 def build_body(self): self.player.body = "怪獸身材" # 被隱藏的產品內部結構,也是表示代碼 def build_arm(self): self.player.arm = "長毛的胳膊" def build_leg(self): self.player.leg = "長毛的腿" class PlayerDirector: # 指揮者:控制組裝順序 def build_player(self, builder): builder.build_body() # 被隱藏的裝配過程,也是構造代碼 builder.build_face() # 被隱藏的裝配過程,也是構造代碼 builder.build_arm() builder.build_leg() return builder.player # client調用 # builder = SexyGirlBuilder() # 建立一個性感女孩builder builder = Monster() # 建立一個怪物builder director = PlayerDirector() # 指揮者實例化 p = director.build_player(builder) # 組裝建立(不一樣角色建立函數都是相同的) print(p)
角色:
優勢:
建造者模式與抽象工廠模式對比:
建造者模式與抽象工廠模式類似,也用來建立複雜對象。主要區別是建造者模式着重一步步構造一個複雜對象(控制它的順序),而抽象工廠模式着重於多個系列的產品對象。
保證一個類只有一個實例,並提供一個訪問它的全局訪問點。
from abc import abstractmethod, ABCMeta # 經過 __new__ 方法是實現單例模式的的一種方式,若是實例對象存在了就直接返回該實例便可,若是尚未,那麼就先建立一個實例,再返回。 class Singleton: def __new__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): # 反射查看是否有_instance的類屬性 cls._instance = super(Singleton, cls).__new__(cls) # 調用父類的__new__方法來建立實例 return cls._instance class MyClass(Singleton): def __init__(self, a): self.a = a a = MyClass(10) b = MyClass(20) print(a.a) # 輸出20 print(b.a) # 輸出20 print(id(a), id(b)) # 4400380840 4400380840, id相同說明二者是同一個實例 # 常應用於日誌文件對象,數據庫鏈接器對象,操做系統文件對象等狀況使用。
角色:
優勢:
抽象工廠模式和建造者模式相比於簡單工廠模式和工廠方法模式而言更靈活也更復雜。
一般狀況下、設計以簡單工廠模式或工廠方法模式開發,當你發現設計須要更大的靈活性時,則向更復雜的設計模式演化。