# 前言 這次是本系列的第11篇 主題是代理模式(Proxy Pattern) # 代理模式 代理模式(Proxy Pattern) 一種結構型設計模式,它為目標物件提供了一個代理物件,代理物件控制對目標物件的訪問。 代理模式的主要目的是在不改變目標物件的前提下,通過代理物件來對目標物件的訪問進行控制或增強功能。 結構: 1. 抽象主題(Subject): 定義目標物件和代理物件的公共接口。 2. 具體主題(Real Subject): 目標物件,實現抽象主題接口,是實際被代理的物件。 3. 代理(Proxy): 實現抽象主題接口,並持有對目標物件的引用。 代理物件負責控制對目標物件的訪問,並可以在調用目標物件的方法之前或之後執行其他操作。 4. 客戶端(Client): 通過代理物件間接訪問目標物件,無需直接與目標物件交互。 其應用場景如下 * 延遲加載(Lazy Initialization): 在需要使用物件時才建立它,避免不必要的資源消耗。 * 訪問控制: 對物件的訪問進行權限檢查,確保只有授權的用戶可以執行操作。 * 遠程代理(Remote Proxy): 將本地調用轉發給遠程物件,例如分散式系統中的代理。 * 日誌或性能監控: 在調用目標物件的方法之前或之後記錄日誌或執行性能統計。 * 緩存代理: 將對目標物件的結果進行緩存,避免重複計算或訪問。 這次我們來模擬`Redis`與`MySQL`之間的關係 ``` 利用Redis做緩存,減少使用者對MySQL的頻繁查詢 可以降低資料庫的壓力 ``` 程式碼實作如下 ```python= from abc import ABC, abstractmethod import time class Database(ABC): # 抽象主題 @abstractmethod def get_value(self): pass class InnerDB(Database): # 具體主題 def __init__(self) -> None: self.log_in() def log_in(self) -> None: print("Log in InnerDB.") def get_value(self) -> None: print("Get a value.") class Cache(Database): # 代理 def __init__(self) -> None: self.inner_db = None def get_value(self): if self.inner_db == None: self.inner_db = InnerDB() self.inner_db.get_value() if __name__ == '__main__': request = Cache() request.get_value() time.sleep(1) # 模擬使用者再次查詢的延遲 request.get_value() ``` 下面是輸出的結果 ``` Log in InnerDB. Get a value. Get a value. ``` 可以看到當使用者第一次發出請求時 會執行`InnerDB().log_in()` 但是第二次發出請求時,就不再登入了 # 心得 這次的模式也不難理解 剛看完解釋的時候就想到這不就是類似於緩存的機制嗎? 結果看到應用場景的時候還真的就有 就用程式碼來模擬redis與mysql(或其他RDBMS)之間的關係 當然這個就只是模擬而已,實際上還有很多地方沒有考慮到 但那不是重點就懶得加上去了
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up