2

Python 设计模式——代理模式

 3 years ago
source link: https://rollingstarky.github.io/2020/12/25/python-design-patterns-proxy-pattern/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python 设计模式——代理模式

发表于 2020-12-25

| 分类于 Python

| 0

| 阅读次数: 1

字数统计: 2.6k

|

阅读时长 ≈ 0:03

代理通常是指一个介于寻求方和提供方之间的中介系统。寻求发是发出请求的一方,而提供方则是根据请求提供资源的一方。
在设计模式中,代理通常是封装实际服务对象的装饰器或代理人,可以为其包装的对象提供附加功能同时无需改变对象本身的代码。其主要目的是为其他对象提供一个代理者或占位符,从而控制对实际对象的访问。

代理设计模式的主要工作:

  • 为其他对象提供代理,实现对原始对象的访问控制
  • 可以用作一个中间层或接口,以支持分布式访问
  • 通过增加代理,保护真正的组件不受意外影响

UML

# agent.py
from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):
@abstractmethod
def do_pay(self):
pass


class Bank(Payment):
def __init__(self):
self.card = None
self.account = None

def __getAccount(self):
self.account = self.card
return self.account

def __hasFunds(self):
print("Bank:: Checking if Account ", self.__getAccount(), " has enough funds")
return True

def setCard(self, card):
self.card = card

def do_pay(self):
if self.__hasFunds():
print("Bank:: Paying the merhant")
return True
else:
print("Bank:: Sorry, not enough funds")
return False


class DebitCard(Payment):
def __init__(self):
self.bank = Bank()

def do_pay(self):
card = input("Proxy:: Punch in Card Number: ")
self.bank.setCard(card)
return self.bank.do_pay()


class You:
def __init__(self):
print("You:: Let's buy the Denim shirt")
self.debitCard = DebitCard()
self.isPurchased = None

def make_payment(self):
self.isPurchased = self.debitCard.do_pay()

def __del__(self):
if self.isPurchased:
print("You:: Denim shirt is Mine :-)")
else:
print("You:: I should earn more :(")


you = You()
you.make_payment()
$ python agent.py
You:: Let's buy the Denim shirt
Proxy:: Punch in Card Number: 12345
Bank:: Checking if Account 12345 has enough funds
Bank:: Paying the merhant
You:: Denim shirt is Mine :-)

关于类 You(对应 UML 图中的 client)的解释:

  • 该类用于实现客户端的行为
  • __init__() 会调用代理并将其实例化
  • make_payment() 方法表示购买动作,会在内部调用代理的付款方法

关于类 Bank(对应 UML 图中的 RealSubject)的解释:

  • 该类实际完成从顾客账户向商家划账的动作(do_pay()
  • 该类提供了多个方法来处理有关付款的一系列逻辑(__getAccount()__hasFunds()do_pay() 等)
  • 通过 setCard() 方法从代理处获取借记卡信息

关于 DebitCard 类(对应 UML 图中的 Proxy)的解释:

  • 该类用于实现代理的行为,充当真实主题(银行)的代理
  • 顾客需要付款时,无需跑去银行提款再回到商家支付,而是调用 DebitCard 的 do_pay() 方法
  • DebitCard 类在内部控制真实主题(Bank)的创建,并向银行提供借记卡的详细信息
  • Bank 对象在内部对账户进行检查并完成支付动作

代理模式的优点

  • 可以通过缓存笨重的对象或频繁访问的对象来提高应用程序的性能
  • 可以提供对于真实对象的访问授权
  • 远程代理还便于与远程服务器进行交互,并监视系统

门面模式与代理模式的比较

代理模式 门面模式 为其他对象提供代理或占位符,以控制对原始对象的访问 为类的大型子系统提供了一个简单的接口 代理对象具有与目标对象相同的接口,并保存目标对象的引用 实现了子系统之间通信和依赖性的最小化 充当客户端和被封装的对象之间的中介 提供了单一的简单接口

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK