sjms-2 建立型模式

設計模式分類

建立型模式(5種):工廠方法模式、抽象工廠模式、建立者模式、原型模式、單例模式
結構型模式(7種):適配器模式、橋模式、組合模式、裝飾模式、外觀模式、享元模式、代理模式
行爲型模式(11種):解釋器模式、責任鏈模式、命令模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態模式、策略模式、訪問者模式、模板方法模式python

建立型模式

簡單工廠模式

內容:不直接向客戶端暴露對象建立的實現細節,而是經過一個工廠類來負責建立產品類的實例。
角色:
工廠角色(Creator)
抽象產品角色(Product)
具體產品角色(Concrete Product)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_huaei = use_huabei

    def 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, abstractmethod


class Payment(metaclass=ABCMeta):
    # abstract class
    @abstractmethod
    def pay(self, money):
        pass


class Alipay(Payment):
    def __init__(self, use_huabei=False):
        self.use_huaei = use_huabei

    def 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):  # 相似做用橋樑
    @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()


# client

pf = HuabeiFactory()
p = pf.create_payment()
p.pay(100)

 

 

優勢:函數

每一個具體產品都對應一個具體工廠類,不須要修改工廠類代碼微信支付

隱藏了對象建立的實現細節ui

缺點:操作系統

每增長一個具體產品類,就必須增長一個相應的具體工廠類(去調用產品)設計

 

抽象工廠模式

內容:定義一個工廠類接口,讓工廠子類來建立一系列相關或相互依賴的對象。
例:生產一部手機,須要手機殼、CPU、操做系統三類對象進行組裝,其中每類對象都有不一樣的種類。對每一個具體工廠,分別生產一部手機所須要的三個對象。
相比工廠方法模式,抽象工廠模式中的每一個具體工廠都生產一套產品。

 

角色:
抽象工廠角色(Creator)
具體工廠角色(Concrete Creator)
抽象產品角色(Product)
具體產品角色(Concrete Product)
客戶端(Client)

from abc import abstractmethod, ABCMeta

# ------抽象產品------

class PhoneShell(metaclass=ABCMeta):
    @abstractmethod
    def show_shell(self):
        pass

class CPU(metaclass=ABCMeta):
    @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()

    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()

  

優勢:
將客戶端與類的具體實現相分離
每一個工廠建立了一個完整的產品系列,使得易於交換產品系列
有利於產品的一致性(即產品之間的約束關係)
缺點:
難以支持新種類的(抽象)產品

 

如要增長手機產品配件,再也不是3個一套,而是更多,就須要大改 。用的較少

 

建造者模式 

內容:將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
角色:
抽象建造者(Builder)
具體建造者(Concrete Builder)
指揮者(Director)
產品(Product)

 

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 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


# client

builder = 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._instance


class MyClass(Singleton):
    def __init__(self, a):
        self.a = a


a = MyClass(10)
b = MyClass(20)

print(a.a)
print(b.a)
print(id(a), id(b))

"""
20
20
1319845376968 1319845376968      
"""

# 日誌對象
# 數據庫連接池

  

建立型模式小結抽象工廠模式和建造者模式相比於簡單工廠模式和工廠方法模式而言更靈活也更復雜。一般狀況下、設計以簡單工廠模式或工廠方法模式開始,當你發現設計須要更大的靈活性時,則像更復雜的設計模式演化。

相關文章
相關標籤/搜索