生活中的代理模式
我们将通过付款用例来展示代理模式的生活中的应用场景。假设你在商场看中了一件衣服,你想买但是手里的现金却不够了。但是你可以刷卡,这笔钱就会划入商家的账户,从而完成支付。
下面我们利用python来开发一个应用程序,实现上面的例子。首先从客户端开始:去了商场,想买一件衣服。
1、你的行为由类You表示;
2、为了购买衣服,该类提供了make_payment()方法;make_payment()方法在内部调用代理的方法进行付款。
3、特殊方法__init__()会调用代理并将其实例化;
3、如果付款成功,将返回__del__()方法
代码如下:
class You(object):
def __init__(self):
print("买衣服")
self.debit_card = DebitCard()
self.is_purchased = None
def make_payment(self):
self.is_purchased = self.debit_card.do_pay()
def __del__(self):
if self.is_purchased:
print("买到了")
else:
print("没买到")
you = You()
you.make_payment()
下面是主题,主题是由代理和真实主题实现的接口
1、在这个例子中,主题是Payment类,它是一个抽象基类,代表一个接口
2、付款具有一个do_pay()方法,该方法需要借助代理和真实主题来实现。
代码如下:
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def do_pay(self):
pass
在这个场景中,我还开发了代表真实主题的Bank类;
1、Bank实际上完成从你账户向商家账户划账的工作。
2、Bank提供了多个方法来处理付款。代理使用set_card()方法将借记卡详细信息发送给银行。
3、__get_account()方法是Bank的私有方法,用于获取借记卡持有人的账号详细信息。
4、Bank还有__has_funds()方法,它用来查看账户持有人在账户中是否有足够的资金来购买衣服。
5、由Bank类(通过Payment接口)实现的do_pay()方法实际上负责可用资金向商家付款。
class Bank(Payment):
def __init__(self):
self.card = None
self.account = None
def __get_account(self):
self.account = self.card
return self.account
def __has_funds(self):
print("检查账户有足够的资金", self.__get_account())
return True
def set_card(self, card):
self.card = card
def do_pay(self):
if self.__has_funds():
print("向商家付款")
return True
else:
print("没有足够的资金")
return False
现在来理解最后一部分,即与代理有关的部分。
1、DebitCard类是此处的类。当你像付款时,它会调用do_play()方法
2、DebitCard类充当真实主题的代理
3、pay_with_card()方法在内部控制真实主题(Bank类)对象的创建,并向银行提供借记卡的详细信息。
4、Bank在内部对帐户进行检查并完成支付。
代码如下:
class DebitCard(Payment):
def __init__(self):
self.bank = Bank()
def do_pay(self):
card = input("请输入你的卡号:")
self.bank.set_card(card)
return self.bank.do_pay()
代理模式的优点
1、代理模式可以通过缓存笨重的对象或频繁访问的对象来提高应用程序的性能
2、代理还提供对于真实主题的访问授权。因此,只有提供合适权限的情况下,这个模式才会接受委派
2、远程代理还便于与可用作网络连接和数据库连接的远程服务器进行交互,并可用于监视系统。
门面模式和代理模式之间的比较
代理模式 | 门面模式 |
它为其他对象提供了代理或占位符,以控制对原始对象的访问 | 它为类的大型子系统提供了一个接口 |
代理对象具有与其目标对象相同的接口,并保存有目标对象的引用 | 它实现可子系统之间的通信和依赖性的最小化 |
它充当客户端和被封装的对象之间的中介 | 门面对象提供了单一的简单接口 |