設計模式分類
創建型模式(5種):工廠方法模式、抽象工廠模式、創建者模式、原型模式、單例模式
結構型模式(7種):適配器模式、橋模式、組合模式、裝飾模式、外觀模式、享元模式、代理模式
行為型模式(11種):解釋器模式、責任鏈模式、命令模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態模式、策略模式、訪問者模式、模板方法模式
創建型模式
簡單工廠模式
內容:不直接向客戶端暴露對象創建的實現細節,而是通過一個工廠類來負責創建產品類的實例。
角色:
工廠角色(Creator)
抽象產品角色(Product)
具體產品角色(Concrete Product)
from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):# abstract class@abstractmethoddef pay(self, money):passclass Alipay(Payment):def __init__(self, use_huabei=False):self.use_huaei = use_huabeidef pay(self, money):if self.use_huaei: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)# client
pf = PaymentFactory()
p = pf.create_payment('huabei')
p.pay(100)
隱藏了內部實現。把好幾種支付方式的創建細節封裝到工廠里面
優點:
隱藏了對象創建的實現細節
客戶端不需要修改代碼
缺點:
違反了單一職責原則,將創建邏輯幾種到一個工廠類里
當添加新產品時,需要修改工廠類代碼,違反了開閉原則
添加新的支付方式,需要去修改工廠函數。
工廠方法模式
內容:定義一個用于創建對象的接口(工廠接口),讓子類決定實例化哪一個產品類。
角色:
抽象工廠角色(Creator)
具體工廠角色(Concrete Creator)
抽象產品角色(Product)? ? ? ??
具體產品角色(Concrete Product)? ?
from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):# abstract class@abstractmethoddef pay(self, money):passclass Alipay(Payment):def __init__(self, use_huabei=False):self.use_huaei = use_huabeidef pay(self, money):if self.use_huaei: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): # 類似作用橋梁@abstractmethoddef create_payment(self):passclass 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()# clientpf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)
優點:
每個具體產品都對應一個具體工廠類,不需要修改工廠類代碼
隱藏了對象創建的實現細節
缺點:
每增加一個具體產品類,就必須增加一個相應的具體工廠類(去調用產品)
抽象工廠模式
內容:定義一個工廠類接口,讓工廠子類來創建一系列相關或相互依賴的對象。
例:生產一部手機,需要手機殼、CPU、操作系統三類對象進行組裝,其中每類對象都有不同的種類。對每個具體工廠,分別生產一部手機所需要的三個對象。
相比工廠方法模式,抽象工廠模式中的每個具體工廠都生產一套產品。
角色:
抽象工廠角色(Creator)
具體工廠角色(Concrete Creator)
抽象產品角色(Product)
具體產品角色(Concrete Product)
客戶端(Client)
from abc import abstractmethod, ABCMeta# ------抽象產品------class PhoneShell(metaclass=ABCMeta):@abstractmethoddef show_shell(self):passclass CPU(metaclass=ABCMeta):@abstractmethoddef show_cpu(self):passclass OS(metaclass=ABCMeta):@abstractmethoddef show_os(self):pass# ------抽象工廠------class PhoneFactory(metaclass=ABCMeta):@abstractmethoddef make_shell(self):pass@abstractmethoddef make_cpu(self):pass@abstractmethoddef 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()def make_os(self):return IOS()def make_shell(self):return AppleShell()# ------客戶端------class Phone:def __init__(self, cpu, os, shell):self.cpu = cpuself.os = osself.shell = shelldef 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()
優點:
將客戶端與類的具體實現相分離
每個工廠創建了一個完整的產品系列,使得易于交換產品系列
有利于產品的一致性(即產品之間的約束關系)
缺點:
難以支持新種類的(抽象)產品
如要增加手機產品配件,不再是3個一套,而是更多,就需要大改 。用的較少
建造者模式?
內容:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
角色:
抽象建造者(Builder)
具體建造者(Concrete Builder)
指揮者(Director)
產品(Product)
from abc import ABCMeta, abstractmethodclass Player:def __init__(self, face=None, body=None, arm=None, leg=None):self.face = faceself.body = bodyself.arm = armself.leg = legdef __str__(self):return "%s, %s, %s, %s" % (self.face, self.body, self.arm, self.leg)class PlayerBuilder(metaclass=ABCMeta):@abstractmethoddef build_face(self):pass@abstractmethoddef build_body(self):pass@abstractmethoddef build_arm(self):pass@abstractmethoddef build_leg(self):passclass 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 MonsterBuilder(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# clientbuilder = MonsterBuilder()
director = PlayerDirector()
p = director.build_player(builder)
print(p)
建造者模式與抽象工廠模式相似,也用來創建復雜對象。主要區別是建造者模式著重一步步構造一個復雜對象,而抽象工廠模式著重于多個系列的產品對象。
優點:
隱藏了一個產品的內部結構和裝配過程
將構造代碼與表示代碼分開
可以對構造過程進行更精細的控制
單例模式
內容:保證一個類只有一個實例,并提供一個訪問它的全局訪問點。
角色:
單例(Singleton)
優點:
對唯一實例的受控訪問
單例相當于全局變量,但防止了命名空間被污染
class Singleton:def __new__(cls, *args, **kwargs):_instance = None # 假定沒有實列if not hasattr(cls, "_instance"): # 如果沒有就創建,有就返回實列cls._instance = super(Singleton, cls).__new__(cls)return cls._instanceclass MyClass(Singleton):def __init__(self, a):self.a = aa = MyClass(10)
b = MyClass(20)print(a.a)
print(b.a)
print(id(a), id(b))"""
20
20
1319845376968 1319845376968
"""# 日志對象
# 數據庫鏈接池
創建型模式小結
抽象工廠模式和建造者模式相比于簡單工廠模式和工廠方法模式而言更靈活也更復雜。
通常情況下、設計以簡單工廠模式或工廠方法模式開始,當你發現設計需要更大的靈活性時,則像更復雜的設計模式演化。
總結
以上是生活随笔為你收集整理的sjms-2 创建型模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。