設計模式一:建立型模式

 


知識儲備:

1.接口:若干抽象方法的集合shell

  做用:限制實現接口的類必須按照接口給定的調用方式實現這些方法;對高層模塊隱藏了類的內部實現。編程

2.面向對象設計SOLID原則設計模式

  • 開放封閉原則:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。即軟件實體應儘可能在不修改原有代碼的狀況下進行擴展。
  • 里氏替換原則:全部引用父類的地方必須能透明的使用其子類的對象。
  • 依賴倒置原則:高層模塊不該該依賴底層模塊,兩者都應該依賴其抽象;抽象不該該依賴細節;細節應該依賴抽象。換言之,要針對接口編程,而不是針對實現編程。
  • 接口隔離原則:使用多個專門的接口,而不使用單一的總接口,即客戶端不該該依賴那些它不須要的接口。
  • 單一職責原則:不要存在多於一個致使類變動的緣由。通俗的說,即一個類只負責某一項職責。

3.設計模式分類微信

建立型模式(5種):工廠方法模式、抽象工廠模式、建立者模式、原型模式、單例模式ide

結構型模式(7種):適配器模式、橋模式、組合模式、裝飾模式、外觀模式、享元模式、代理模式函數

行爲型模式(11種):解釋器模式、責任鏈模式、命令模式、迭代器模式、中介者模式、備忘錄模式、觀察者模式、狀態模式、策略模式、訪問者模式、模板方法模式微信支付

 

一、簡單工廠模式

內容:不直接向客戶端暴露對象建立的實現細節,而是經過一個工廠類來負責建立產品類的實例。ui

角色:spa

  • 工廠角色(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_hubei = use_huabei

    def pay(self, money):
        if self.use_hubei:
            print("花唄支付%d元" % money)
        else:
            print("支付寶餘額支付%d" % money)


class Wechat(Payment):
    def pay(self, money):
        print("微信支付%d元" % money)


# 工廠類
class PaymentFactory:
    def create_payment(self, method):
        if method == 'alipay':
            return Alipay()
        elif method == 'wechat':
            return Wechat()
        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)


## 
工廠角色: PaymentFactory
抽象產品角色:Payment
具體產品角色:Alipay,WechatPay
View Code

優勢:操作系統

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

  2.客戶端不須要修改代碼

缺點:

  1.違反了單一職責原則,將建立邏輯集中到一個工廠類裏

  2.當添加新產品時,須要修改工廠類代碼,違反了開閉原則

 

二、工廠方法模式

內容:定義一個用於建立對象的接口(工廠接口),讓子類決定實例化哪個產品類。

角色:

  • 抽象工廠角色(Creator)
  • 具體工廠角色(Concrete Cretor)
  • 抽象產品角色(Product)
  • 具體產品角色(Concrete Product)
from abc import ABCMeta, abstractmethod

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


class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):
        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 Wechat(Payment):
    def pay(self, money):
        print("微信支付%d元" %money)


class AlipayFactory(PaymentFactory):
    def create_payment(self):
        return Alipay()


class WechatPayFactory(PaymentFactory):
    def create_payment(self):
        return Wechat()



# client

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


##
    抽象工廠角色:PaymentFactory
    具體工廠角色:AliFactory,WechatFactory
    抽象產品角色:Payment
    具體產品角色:AliPay,WechatPay
View Code

優勢:

  1.每一個產品都對應一個具體工廠類,不須要修改修改共產類代碼

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

缺點:

  1.每增長一個具體產品類,就必須增長一個相應的具體工廠類

 

三、抽象工廠模式

內容:定義一個工廠類接口,讓工廠子類來建立一系列相關或相互依賴的對象。

例:生產一部手機,須要手機殼、CPU、操做系統三類對象進行組裝,其中每類都有不一樣的種類。對每一個具體工廠,分別生產一部手機所須要的三個對象。

相比工廠方法模式,抽象工廠模式中的每一個具體工廠都生產一套產品。

角色:

  • 抽象工廠角色(Creator)
  • 具體工廠角色(Concrete Cretor)
  • 抽象產品角色(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()
View Code

優勢:

  1.將客戶端與類的具體實現相分離

  2.每一個工廠建立了一個完整的產品系列,使得易於交換產品系列

  3.有利於產品一致性(即產品之間的約束關係)

缺點:

  1.難以支持新種類的(抽象)產品

 

四、建立者模式

內容:將一個複雜對象的構造與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。

角色:

  • 抽象建造者(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 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 = Monster()
director = PlayerDirector()
p = director.build_player(builder)
print(p)


##
    抽象建造者:PlayerBuilder
    具體建造者:SexyGirlBuilder, Monster
    指揮者:PlayerDirector
    產品:p
View Code

建造者模式與抽象工廠模式相似,也用來建立複雜對象。主要區別是建造者模式着重一步步構造一個複雜對象,而抽象工廠模式着重於多個系列的產品對象。

優勢:

    1.隱藏了一個產品的內部結構和裝配過程

  2.將構造代碼與表示代碼分開

  3.能夠對構造過程更精細的控制 

 

五、單例模式

內容:保證一個類只有一個實例,並提供一個訪問它的全局訪問點

角色:

  • 單例

優勢:

  1.對惟一實例的受控訪問

  2.單例至關於全局變量,但防止了命名空間被污染。

class Singleton:
    def __new__(cls, *args, **kwargs):
        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))
View Code

 

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