生活中的代理模式
我們將通過付款用例來展示代理模式的生活中的應用場景。假設你在商場看中了一件衣服,你想買但是手裏的現金卻不夠了。但是你可以刷卡,這筆錢就會劃入商家的賬戶,從而完成支付。
下面我們利用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、遠程代理還便於與可用作網絡連接和數據庫連接的遠程服務器進行交互,並可用於監視系統。
門面模式和代理模式之間的比較
代理模式 | 門面模式 |
它爲其他對象提供了代理或佔位符,以控制對原始對象的訪問 | 它爲類的大型子系統提供了一個接口 |
代理對象具有與其目標對象相同的接口,並保存有目標對象的引用 | 它實現可子系統之間的通信和依賴性的最小化 |
它充當客戶端和被封裝的對象之間的中介 | 門面對象提供了單一的簡單接口 |