文章目錄
- 適配器模式
- 橋接模式
- 組合模式
- 外觀模式
- 代理模式
適配器模式
- 將一個類的接口轉換成客戶希望的另一個接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
- 兩種實現方式:
- 類適配器:使用多繼承
- 對象適配器:使用組合
# 適配器模式
from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):@abstractmethoddef pay(self, money):passclass 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 NewBankPay(Payment, BankPay):
# def pay(self, money):
# self.cost(money)# 對象適配器
class PaymentAdapter(Payment):def __init__(self, payment):self.payment = paymentdef pay(self, money):self.payment.cost(money)p = PaymentAdapter(BankPay())
p.pay(100)
橋接模式
- 將一個事物的兩個維度分離,使其都可以獨立地變化。
from abc import ABCMeta, abstractmethodclass Shape(metaclass=ABCMeta):def __init__(self, color):self.color = color@abstractmethoddef draw(self):passclass Color(metaclass=ABCMeta):@abstractmethoddef paint(self, shape):passclass Rectangle(Shape):name = "長方形"def draw(self):# TODO:矩形邏輯self.color.paint(self)class Circle(Shape):name = "圓形"def draw(self):# TODO:原型邏輯self.color.paint(self)class Red(Color):def __init__(self,shape):self.shape=shapedef paint(self):print("紅色的%s" % self.shape.name)class Green(Color):def __init__(self,shape):self.shape=shapedef paint(self):print("綠色的%s" % self.shape.name)shape = Rectangle(Red())
shape.draw()shape2 = Circle(Green())
shape2.draw()
組合模式
- 將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式是用戶對單個對象和組合對象的使用都具有一致性。
- 角色:
- 抽象組件(Component)
- 葉子組件(Leaf)
- 復合組件(Composite)
- 客戶端(Client)
from abc import ABCMeta, abstractmethod
# 抽象組件class Graphic(metaclass=ABCMeta):@abstractmethoddef draw(self):pass# 葉子組件
class Point(Graphic):def __init__(self, x, y):self.x = xself.y = ydef __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 = p1self.p2 = p2def __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("*"* 100)print("----復合圖形 start----")for g in self.children:g.draw()print("----復合圖形 end----")# 線段
l = Line(Point(1, 1), Point(2, 2))
print(l)# 點跟線組合
p1 = Point(2, 3)
l1 = Line(Point(2, 4), Point(6, 7))
l2 = Line(Point(1, 5), Point(2, 8))
pic1 = Picture([p1, l1, l2])
# pic1.draw()# pic1跟 pic2再次組合
l3 = Line(Point(2, 4), Point(6, 7))
l4 = Line(Point(1, 5), Point(2, 8))
pic2 = Picture([l3, l4])
pic3 = Picture([pic1, pic2])
pic3.draw()
# 此處csdn運行代碼可能出問題,理論上應該有三次**********
外觀模式
- 為子系統的一組接口提供一個一致的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
- 角色:
- 外觀(Facade)
- 子系統類(Sub system 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: # Facadedef __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.memory.stop()self.disk.stop()self.cpu.stop()computer = Computer()
computer.run()
print(f"計算機正在運行。。。")
computer.stop()
代理模式
- 為其他對象提供一種代理以控制對這個對象的訪問
- 應用場景:
- 遠程代理:為遠程的對象提供代理
- 虛代理:可在需要時才創建對象,減少內存消耗
- 保護代理:控制對原始對象的訪問,用于對象有不同訪問權限時
建議在py源文件同級目錄下創建一個test.txt文件
Initial Context.
"""
角色:抽象實體(Subject)實體(RealSubject)代理(Proxy)
"""from abc import ABCMeta, abstractmethodclass Subject(metaclass=ABCMeta):@abstractmethoddef get_content(self):pass@abstractmethoddef set_content(self, content):passclass RealSubject(Subject):def __init__(self, filename):self.filename = filename# 嘗試讀取文件,如果文件不存在則初始化為空內容try:with open(filename, 'r') as f:self.content = f.read()except FileNotFoundError:self.content = ""def get_content(self):return self.contentdef set_content(self, content, new_filename=None):# 如果提供了新文件名,則更新當前實例的文件名if new_filename:self.filename = new_filename# 寫入內容(如果文件不存在會自動創建)with open(self.filename, 'w') as f:f.write(content)self.content = contentclass VirtualProxy(Subject):def __init__(self, filename):self.filename = filenameself.subj = Nonedef get_content(self):if not self.subj:self.subj = RealSubject(self.filename)return self.subj.get_content()def set_content(self, content):if not self.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.set_content("Testing Context.")
print(subj.get_content())print("---- VirtualProxy")
v_subj = VirtualProxy("test.txt")
print(v_subj.get_content())print("---- ProtectedProxy")
p_subj = ProtectedProxy("test.txt")
print(p_subj.get_content())
# p_subj.set_content("aaa")
# 會輸出PermissionError