sjms-3 結構型模式

結構型模式

適配器模式

內容:將一個類的接口轉換成客戶但願的另外一個接口。適配器模式使
得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
兩種實現方式:
類適配器:使用多繼承
對象適配器:使用組合python

 

角色:
目標接口(Target)
待適配的類(Adaptee)
適配器(Adapter)
適用場景:
想使用一個已經存在的類,而它的接口不符合你的要求(對象適配器)想使用一些已經存在的子類,但不可能對每個都進行子類化以匹配它們的接口。對象適配器能夠適配它的父類接口。安全

from abc import ABCMeta, abstractmethod

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

class Alipay(Payment):
    def pay(self, money):
        print("支付寶支付%d元." % money)

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


class BankPay:
    def cost(self, money):
        print("銀聯支付%d元." % money)

class ApplePay:
    def cost(self, money):
        print("蘋果支付%d元." % money)

# # 類適配器
# class NewBankPay(Payment, BankPay):
#     def pay(self, money):
#         self.cost(money)# 把不兼容的轉成兼容的
# 當有多個接口不一樣的類時,這樣會致使要寫多個類去繼承


# 對象適配器
class PaymentAdapter(Payment):
    def __init__(self, payment):
        self.payment = payment

    def pay(self, money):
        self.payment.cost(money)  # 調用不兼容對象的方法  , 包裝 不兼容的接口方法 成兼容的


p = PaymentAdapter(BankPay())         # 一個類裏放另外一個類對象
p.pay(100)


# 組合

# class A:
#     pass
#
# class B:
#     def __init__(self):
#         self.a = A()

  

橋模式


內容:
  將一個事物的兩個維度分離,使其均可以獨立地變化。微信

 

角色:
抽象(Abstraction)
細化抽象(RefinedAbstraction)
實現者(Implementor)
具體實現者(ConcreteImplementor)app

 

應用場景:
當事物有兩個維度上的表現,兩個維度均可能擴展時。
優勢:
抽象和實現相分離
優秀的擴展能力微信支付

 

from abc import ABCMeta, abstractmethod

class Shape(metaclass=ABCMeta):
    def __init__(self, color):
        self.color = color
    @abstractmethod
    def draw(self):
        pass


class Color(metaclass=ABCMeta):
    @abstractmethod
    def paint(self, shape):
        pass


class Rectangle(Shape):
    name = "長方形"
    def draw(self):
        # 長方形邏輯
        self.color.paint(self)


class Circle(Shape):
    name = "圓形"
    def draw(self):
        # 圓形邏輯
        self.color.paint(self)   # 調用color 對象的paint並把self形狀對象傳過去,方便color的paint打印


class Line(Shape):
    name = "直線"
    def draw(self):
        # 直線邏輯
        self.color.paint(self)


class Red(Color):
    def paint(self, shape):
        print("紅色的%s" % shape.name)


class Green(Color):
    def paint(self, shape):
        print("綠色的%s" % shape.name)


class Blue(Color):
    def paint(self, shape):
        print("藍色的%s" % shape.name)


shape = Line(Blue())
shape.draw()

shape2 = Circle(Green()) # 先把color對象傳過來,以便draw調用
                         # (其實draw調用的時候,是調用color的paint方法,並把shape對象傳給paint讓它去調用shape的name)
shape2.draw()

# 兩個維度均可以擴展

  

組合模式 

內容:將對象組合成樹形結構以表示「部分-總體」的層次結構。組合模式使得用戶對單個對象和組合對象的使用具備一致性。
角色:
抽象組件(Component)
葉子組件(Leaf)
複合組件(Composite)
客戶端(Client)優化

 

from abc import ABCMeta, abstractmethod

# 抽象組件
class Graphic(metaclass=ABCMeta):
    @abstractmethod
    def draw(self):
        pass

# 葉子組件
class Point(Graphic):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return "點(%s, %s)" % (self.x, self.y)

    def draw(self):
        print(str(self))

# 葉子組件
class Line(Graphic):
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    def __str__(self):
        return "線段[%s, %s]" % (self.p1, self.p2)

    def draw(self):
        print(str(self))


# 複合組件
class Picture(Graphic):                    # 組合(組裝類)
    def __init__(self, iterable):
        self.children = []
        for g in iterable:
            self.add(g)

    def add(self, graphic):
        self.children.append(graphic)

    def draw(self):
        print("------複合圖形------")
        for g in self.children:
            g.draw()
        print("------複合圖形------")


p1 = Point(2,3)
l1 = Line(Point(3,4), Point(6,7))    # 將簡單的類對象,做爲參數傳遞進行組合
l2 = Line(Point(1,5), Point(2,8))
pic1 = Picture([p1, l1, l2])


p2 = Point(4,4)
l3 = Line(Point(1,1), Point(0,0))
pic2 = Picture([p2, l3])

pic = Picture([pic1, pic2])
pic.draw()

"""
------複合圖形------
------複合圖形------
點(2, 3)
線段[點(3, 4), 點(6, 7)]
線段[點(1, 5), 點(2, 8)]
------複合圖形------
------複合圖形------
點(4, 4)
線段[點(1, 1), 點(0, 0)]
------複合圖形------
------複合圖形------
"""

  

適用場景:
表示對象的「部分-總體」層次結構(特別是結構是遞歸的)
但願用戶忽略組合對象與單個對象的不一樣,用戶統一地使用組合結構中的全部對象
優勢:
定義了包含基本對象和組合對象的類層次結構
簡化客戶端代碼,即客戶端能夠一致地使用組合對象和單個對象
更容易增長新類型的組件代理

外觀模式


內容:爲子系統中的一組接口提供一個一致的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
角色:
外觀(facade)
子系統類(subsystem classes)對象

class CPU:
    def run(self):
        print("CPU開始運行")

    def stop(self):
        print("CPU中止運行")


class Disk:
    def run(self):
        print("硬盤開始工做")

    def stop(self):
        print("硬盤中止工做")


class Memory:
    def run(self):
        print("內存通電")

    def stop(self):
        print("內存斷電")


class Computer: # Facade
    def __init__(self):
        self.cpu = CPU()
        self.disk = Disk()
        self.memory = Memory()

    def run(self):
        self.cpu.run()
        self.disk.run()
        self.memory.run()

    def stop(self):
        self.cpu.stop()
        self.disk.stop()
        self.memory.stop()

computer = Computer()          # 高級別的封裝調用,使外觀調用一致
computer.run()
computer.stop()

  

優勢:
減小系統相互依賴
提升了靈活性
提升了安全性blog

 

代理模式

 

內容:爲其餘對象提供一種代理以控制對這個對象的訪問。
應用場景:
遠程代理:爲遠程的對象提供代理
虛代理:根據須要建立很大的對象
保護代理:控制對原始對象的訪問,用於對象有不一樣訪問權限時繼承

 

from abc import ABCMeta, abstractmethod

class Subject(metaclass=ABCMeta):
    @abstractmethod
    def get_content(self):
        pass

    @abstractmethod
    def set_content(self, content):
        pass

class RealSubject(Subject):
    def __init__(self, filename):
        self.filename = filename
        with open(filename, 'r', encoding='utf-8') as f:
            print("讀取文件內容")
            self.content = f.read()

    def get_content(self):
        return self.content

    def set_content(self, content):
        with open(self.filename, 'w', encoding='utf-8') as f:
            f.write(content)


class VirtualProxy(Subject):
    def __init__(self, filename):     # 不直接調用文件,防止文件過大,佔到內存到
        self.filename = filename     # 建立對象時不會讀取文件內容,
        self.subj = None

    def get_content(self):
        if not self.subj:
            self.subj = RealSubject(self.filename)  # 在調用get_content 時才真正去打開文件
        return self.subj.get_content()


    def set_content(self, content):
        if not subj:
            self.subj = RealSubject(self.filename)
        return self.subj.set_content(content)



class ProtectedProxy(Subject): # 保護代理
    def __init__(self, filename):
        self.subj = RealSubject(filename)

    def get_content(self):
        return self.subj.get_content()

    def set_content(self, content):
        raise PermissionError("無寫入權限")


#subj = RealSubject("test.txt")
#subj.get_content()

subj = ProtectedProxy("test.txt")
print(subj.get_content())
# subj.set_content("abc")

  

角色:抽象實體(Subject)實體(RealSubject)代理(Proxy)優勢:遠程代理:能夠隱藏對象位於遠程地址空間的事實虛代理:能夠進行優化,例如根據要求建立對象保護代理:容許在訪問一個對象時有一些附加的內務處理

相關文章
相關標籤/搜索