代理模式

代理模式

定義

爲其餘對象提供一種代理以控制對這個對象的訪問。設計模式

優點

隱藏被代理類的實現細節緩存

解耦代理類與被代理類,能夠在沒法修改被代理類的狀況下爲被代理類添加額外的行爲。安全

缺點

和其餘的包裝者同樣,代理會形成設計中類的數量增長。服務器

應用場合

  1. 遠程代理,爲一個對象在不一樣的地址空間提供局部表明。這樣能夠隱藏一個對象存在於不一樣地址空間的事實。
  2. 虛擬代理,根據須要建立開銷很大的對象。經過它來存放實例化須要很長時間的真實對象。
  3. 安全代理,用來控制真實對象訪問時的權限。
  4. 智能指引,當調用真實的對象時,代理處理另一些事。

Example

遠程代理

目的:管理客戶和遠程對象之間的交互網絡

  • Client — Server

假如這裏有一個天氣查詢的 App。用戶在手機上輸入想要查詢的城市,點擊開始查詢。客戶端向服務器發送一個網絡請求。服務器根據請求參數找到對應結果,經過網絡返回。客戶端展現查詢結果。操作系統

在這麼一個流程中。咱們把客戶端,服務器看做一個提供天氣查詢服務的總體。客戶端和服務器分別做爲這個總體其中的一個模塊。以下圖,那麼圖中的 Repo 做爲 WeatherService 的替身,能夠認爲是一種遠程代理。線程

  • 跨進程調用

在操做系統中,兩個進程是被隔離開的,A 進程沒法訪問 B 進程的內存空間。設計

在 Android 系統中,有一些操做是須要跨進程通訊的,好比啓動一個新的 Activity 須要和 ActivityManagerService 進行一些交互。此時,Android 系統經過 Binder 機制,使 Client 端持有 ActivityManagerService 的代理對象,經過這個代理對象與真實的 ActivityManagerService 進程進行通訊。如圖代理

虛擬代理

目的:控制訪問實例化開銷大的對象指針

虛擬代理做爲建立開銷大的對象的表明,常常直到咱們真正須要一個對象的時候才建立它。

比較典型的用法是 Kotlin 中的 Lazy。

Android 中的 SharedPreference 在首次加載某個 SharedPreference 文件中的某個值的時候,須要先將對應文件中的全部 KeyValue 所有加載。爲了下降此次文件加載對於 App 流暢度的影響,咱們每每會選擇使用 Lazy 將 SharedPreference 對象的初始化延遲到真正使用的時候。

安全代理

目的:控制調用者對對象方法的訪問

經過 Java 提供的動態代理技術,在沒法修改被代理類的狀況下爲被代理類添加額外的行爲。

好比,咱們可使用代理模式封裝一個不支持多進程特性的第三方 Lib。在代理類中限制這個第三方 Lib 的 API 只容許在 UI 進程中調用。

智能指引

目的:調用真實對象時,代理處理另一些事。

好比 C++ 的智能指針,能夠完成引用計數的功能,在對象使用完畢後自動釋放內存,防止內存泄漏。

好比 Android Native 層有模仿 Java 的強引用和弱引用的 Strong PointerWeak Pointer,一樣是給對象增長引用計數的功能,達到使用完畢後自動釋放內存的效果。

好比 Java 中 Collections 類提供的 synchronizedCollection 等方法,能夠爲普通的 Collection 對象添加線程安全的特性。

其餘變體

防火牆代理:控制網絡資源的訪問

緩存代理:爲開銷大的運算結果提供暫時存儲,也容許多個客戶共享結果,以減少計算或網絡延遲

寫入時複製代理: CopyOnWriteArrayList

和適配器模式的區別

適配器模式是將一個類的接口轉換成客戶但願的另一個接口。使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。

和裝飾器模式的區別

裝飾器模式主要是爲對象增長行爲。

代理模式能夠做爲被代理對象的替身,能夠避免不想要的訪問,隱藏對象在遠程運行的事實,在被代理對象未建立完成時對調用做出響應,等等。

裝飾器模式只起到裝飾點綴的做用,不會實例化被代理對象。

裝飾器模式能夠很容易的連續將對象包裝屢次,而用代理模式的意圖每每並非將對象連續包裝屢次。

和外觀模式的區別

外觀模式的目的是提供一個簡單的接口,讓子系統更加容易使用。

Refs

Head First 設計模式

大話設計模式


@Eric

相關文章
相關標籤/搜索