Android中的设计模式之代理模式
生活随笔
收集整理的這篇文章主要介紹了
Android中的设计模式之代理模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
參考
- 《設計模式:可復用面向對象軟件的基礎 》4.7 Proxy 代理--對象結構型模式
- 《Android源碼設計模式解析與實戰》第18章 編程好幫手--代理模式
意圖
為其它對象提供一種代理以控制對這個對象的訪問
適用性
在需要用比較通用和復雜的對象指針代替簡單的指針的時候,使用Proxy模式。
- 遠程代理 為一個對象在不同的地址空間提供局部代表。這一點Android Binde實現跨進程通信很典型
- 虛代理 根據需要創建開銷很大的對象。
- 保護代理 控制對原始對象的訪問。保護代理用于對象應該有不同的訪問權限的時候。
- 智能指引 取代了簡單的指針,它在訪問對象時執行一些附加操作。
- 對指向實際對象的引用計數,這樣當該對象沒有引用時,可以自動釋放它,難道Java就是這個原理?
- 當第一次引用一個持久對象時,將它裝入內存
- 在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其它對象不能改變它。
結構
代理模式結構角色
- Client
客戶類,即使用代理類的類型
- Subject 抽象主題類 抽象了代理行為
主要職責是聲明真實主題與代理的共同接口關系,該類既可以是一個抽象類也可以是一個接口。
- RealSubject 實現抽象主題的真實主題類
被委托類或被代理類,定義了代理所表示的真實對象,由其執行具體的業務邏輯方法,而客戶端則通過代理類間接地調用真實主題類中定義的方法。
- Proxy 委托類或代理類
- 持有對真實主題類的引用,可以訪問真實實體
- 提供一個與Subject的接口相同的接口,這樣代理就可以用來替代實體
- 控制對實體的存取,并可能負責創建或者刪除它
- 相對與實體的其它附加功能依賴于代理的類型
協作
代理根據其種類,在適當的時候向RealSubject轉發請求
代理執行流程效果
Proxy模式在訪問對象時引入了一定程度的間接性。根據代理的類型,附件的間接性有多種用途
- Remote Proxy可以隱藏一個對象存在不同地址空間的事實。
- Virtual Proxy 可以進行優化,例如根據要求創建對象。
- Protection Proxies和Smart Reference都允許在訪問一個對象時有一些附加的內務處理
應用例子1 小明打官司
描述
小明被老板拖欠工資,小明選擇了走發法律途徑解決該糾紛。所以小明請律師作為自己的訴訟代理人。
結構
結構java實現
/** * * @author newtrekwang * @desc 代理接口 * 2017年3月4日 */ public interface ILawSuit { // 提交申請void submit(); // 進行舉證void burden(); // 開始辯護void defend(); // 訴訟完成void finish(); }/** * * @author newtrekwang * @desc 被代理者小明 * 2017年3月4日 */ public class XiaoMin implements ILawSuit{@Overridepublic void submit() {//小明申請仲裁System.out.println("老板拖欠工資,特此申請仲裁!");}@Overridepublic void burden() {System.out.println("這是合同書和過去一年的銀行工資流水");}@Overridepublic void defend() {System.out.println("證據確鑿,不需要再說什么了");}@Overridepublic void finish() {System.out.println("訴訟成功!判決老板即日起七天內結算工資!");}}/** * * @author newtrekwang * @desc 代理律師 * 2017年3月4日 */ public class Lawyer implements ILawSuit { // 持有一個具體被代理者的引用private ILawSuit mLawSuit;public Lawyer(ILawSuit iLawSuit) {this.mLawSuit=iLawSuit;}@Overridepublic void submit() {mLawSuit.submit();}@Overridepublic void burden() {mLawSuit.burden();}@Overridepublic void defend() {mLawSuit.defend();}@Overridepublic void finish() {mLawSuit.finish();}}客戶使用
public static void main(String[] args) {ILawSuit xiaoMin=new XiaoMin();Lawyer lawyer=new Lawyer(xiaoMin);lawyer.submit();lawyer.burden();lawyer.defend();lawyer.finish();}結果
老板拖欠工資,特此申請仲裁! 這是合同書和過去一年的銀行工資流水 證據確鑿,不需要再說什么了 訴訟成功!判決老板即日起七天內結算工資!java的靜態代理和動態代理
- 靜態代理:靜態代理如上述代碼一樣,代理者的代碼由程序員自己或通過一些自動化工具生成固定的代碼再對其進行編譯,也就是說我們的代碼運行前代理類的class編譯文件就已存在;
- 動態代理:與靜態代理相反,通過反射機制動態地生成代理者的對象,也就是說我們在code階段不知道要代理誰,代理誰我們將會在執行階段決定。而Java也給我們提供了一個便捷的動態代理接口InvocationHandler,實現該接口需要重寫其調用方法invoke.
使用
public static void main(String[] args) { // 構造一個小明ILawSuit xiaoMin=new XiaoMin(); // 構造一個動態代理DynamicProxy dynamicProxy=new DynamicProxy(xiaoMin); // 獲取被代理類小明的ClassLoaderClassLoader loader=xiaoMin.getClass().getClassLoader(); // 動態構造一個代理者律師ILawSuit lawyer=(ILawSuit) Proxy.newProxyInstance(loader, new Class[]{ILawSuit.class}, dynamicProxy);lawyer.submit();lawyer.burden();lawyer.defend();lawyer.finish();}結果
老板拖欠工資,特此申請仲裁! 這是合同書和過去一年的銀行工資流水 證據確鑿,不需要再說什么了 訴訟成功!判決老板即日起七天內結算工資!應用例子2 嵌入圖形對象的文檔編輯器
描述
對一個對象進行訪問控制的一個原因時為了只有在我們真正需要這個對象時才對它進行創建和初始化。考慮一個可以在文檔中嵌入圖形對象的文檔編輯器,有些圖形對象(大圖)的創建開銷很大,但是打開文檔必須很迅速,因此我們在打開文檔時應避免一次性創建所有開銷很大的對象,因為并非所有這些對象在文檔中都同時可見,所以也沒有必要同時創建這些對象。
這一限制條件意味著,對于每一個開銷很大的對象,應該根據需要進行創建。問題的解決方案就是使用另一個對象,即圖像Proxy,代替那個真正的圖像。Proxy可以代替一個圖像對象,并且在需要時負責實例化這個圖像對象。
結構
結構源碼就略了
應用例子3 Retrofit 中的動態代理
待更
應用例子4 Android Service代理
待更
總結
以上是生活随笔為你收集整理的Android中的设计模式之代理模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx: [error] open(
- 下一篇: android sina oauth2.