1. 程式人生 > >結構型: 代理模式(Proxy Pattern)

結構型: 代理模式(Proxy Pattern)

代理模式(Proxy Pattern)

代理模式(Proxy Pattern)為訪問物件提供一個代理物件來實現對被訪問者的訪問,其實就是在訪問物件與被訪問物件之間新增一箇中介,用來隔離訪問者與被訪問者的具體實現細節。

代理模式(Proxy Pattern)屬於結構型模式。結構型模式涉及到如何組合類和物件以獲得更大的結構;結構型類模式採用繼承機制來組合介面或實現。結構型模式主要包括:Adapter模式、Bridge模式、Composite模式、Decorator模式、Facade模式、Flyweight模式和Proxy模式。結構型類模式在某種程度上具有相關性。

模式簡介

GOF的《設計模式》指出Proxy模式的意圖是: 為訪問物件提供一個代理物件來實現對被訪問者的間接訪問。

對一個物件進行訪問控制的一個原因是為了只有在我們確實需要這個物件時才對它進行建立和初始化。在影象處理應用中,我們操作的目標是影象物件,該問題的解決方式是提供一個虛擬的影象影象,即影象Proxy,替代那個真正的影象。 Prox可以代替一個影象物件,並且在需要時負責例項化這個影象物件。

Proxy模式適用於以下場景:

  • 遠端代理(Remote Proxy)為一個物件在不同的地址空間提供區域性代表。
  • 虛代理(Virtual Proxy)根據需要建立開銷很大的物件,諸如ImageProxy。
  • 保護代理(Protection Proxy)控制對原始物件的訪問。保護代理用於物件應該有不同的訪問許可權的時候。
  • 智慧指標(Smart Reference)取代了簡單的指標,它在訪問物件時執行一些附加操作。

模式圖解

Proxy模式的UML示例如下:

Proxy模式示例

Proxy模式的工作過程如下:

  • 抽象物件(Subject):聲明瞭目標物件和代理物件的共同介面;
  • 目標物件(RealSubsuject):被代理或者被訪問的物件;
  • 代理物件(Proxy):代理物件內部持有目標物件的引用,代理物件與目標物件實現相同的介面,Client 訪問代理物件相當於間接訪問目標物件。

Proxy模式的有益效果如下:

  • 降低訪問者與被訪問者之間的耦合度
  • 可以控制訪問者對被訪問者的訪問許可權
  • 虛擬代理通過使用一個小物件來代理一個大物件,可以減少系統開銷
  • 代理物件會增加邏輯的複雜度並且減慢對目標物件的訪問速度

Abstract Factory 模式可以用來建立和配置一個特定的Proxy模式。Adapter模式用來幫助無關的類協同工作,它通常在系統設計完成後才會被使用。然而,Proxy模式則是在系統開始時就被使用,它使得抽象介面和實現部分可以獨立進行改變。

模式例項

Android Binder 類是實現程序間通訊的媒介,由於程序間通訊貫穿四大元件使用的始末,所以在 Android 開發過程中程序間通訊隨處可見,而 Android Binder IPC 模型是基於代理模式。Android Binder IPC 通訊模型:

  • Client : 持有 Server 的本地 Binder 物件的代理物件;
  • Server : 持有本地 Binder 物件,為 Client 端提供功能性服務;
  • ServiceManager : 負責管理 Binder 服務,可以根據 Binder Name 獲取 Binder 引用,功能類似於 DNS 伺服器;
  • Binder 驅動 : Client 與 Server ,以及 Server 與 ServiceManager 之間的通訊都會經過 Binder 驅動,維持 Binder - Proxy 與 Binder 實體引用之間的對映,根據 Client 端由 Binder Proxy 打包傳送過來資料包,呼叫 Server 方法,再將返回結果打包由 Binder Proxy 傳回 Client 端。

在Choices作業系統中KernelProxies為作業系統物件提供了訪問保護,即採用了保護代理(Protection Proxy)。

在電腦科學領域中,提供垃圾收集(Garbage Collection)功能的系統框架,即提供物件託管功能的系統框架,例如Java應用程式框架,也是採用上述的引用計數技術方案來實現自動垃圾回收。Apple公司提出的Cocoa框架,當父物件要引用子物件時,就對子物件使用強引用計數技術,而當子物件要引用父物件時,就對父物件使用弱引用計數技術,而當垃圾收集系統執行物件回收工作時,只要發現物件的強引用計數為0,而不管它的弱引用計數是否為0,都可以回收這個物件。

Android系統提供了強大的智慧指標技術:輕量級指標(Light Pointer)、強指標(Strong Pointer)和弱指標(Weak Pointer)。它們的實現框架都是一致的,即由物件本身來提供引用計數器,但是它不會去維護這個引用計數器的值,而是由智慧指標來維護。

  • 輕量級指標(LightRefBase):請參考frameworks/base/include/utils/RefBase.h
  • 弱指標(RefBase-wp): 請參考frameworks/base/include/utils/RefBase.h
  • 強指標(RefBase-sp): 請參考frameworks/base/include/utils/RefBase.h