1. 程式人生 > >Java設計模式之代理模式(Proxy)

Java設計模式之代理模式(Proxy)

前言:

      最近在研究Retrofit開源框架的時候,其主要核心程式碼是通過註解標示引數,動態代理模式實現具體介面,反射機制進行引數解析,最終實現傳送請求。其實之前在學習Xutils原始碼的時候,Xutils 的task也是通過代理模式來訪問的。為何要採用代理模式呢?有什麼好處呢?抱著這些疑問!今天來學習總結一下。

 什麼是代理模式?

       代理模式的定義:代理模式給某一個物件提供一個代理物件,並由代理物件控制對原物件的引用。舉例說明,就是一個人或者一個機構代表另一個人或者另一個機構採取行動。在一些情況下,一個客戶不想或者不能夠直接引用一個物件,而代理物件可以在客戶端和目標物件之前起到中介的作用。

應用場景舉例:

       通過上面的代理模式描述我們可以知道,其目的就是為了控制物件引用,生活場景中我們以買車為例,如果我們要買一輛轎車必須通過汽車4S店,汽車4s店就是充當代理角色,其目的就是控制買車客戶的買車行為,必須通過汽車4S店才能從汽車廠商買一輛車。

1.)首先新建一個買車的介面

public interface IBuyCar {
    //買車
    void buyCar();
}

2.)宣告一個要買車的客戶,實現買車介面

public class Customer implements IBuyCar {

    private int
cash;//購車款 public int getCash() { return cash; } public void setCash(int cash) { this.cash = cash; } @Override public void buyCar() { Log.e("buyCar", "買一輛車花費了-->" + cash + "元"); } }

3.)宣告一個買車代理汽車4S店,同樣也實現買車介面,必須接受客戶下單

public
class BuyCarProxy implements IBuyCar{ private Customer customer;//接收買車客戶 public BuyCarProxy(Customer customer){ this.customer=customer;//接收買車客戶 } @Override public void buyCar() {//實現為客戶買車 customer.buyCar(); } }

4.)建立一個客戶端,模擬一次買車

  Customer customer=new Customer();
  customer.setCash(120000);
  BuyCarProxy buyCarProxy=new BuyCarProxy(customer);
  buyCarProxy.buyCar();

5.)通過代理模式實現許可權控制

  通過上面的例子,我們可能有個疑問,難道就不能直接去廠家買車嗎?當然可以,如果在使用場景中實現類能滿足要求時,我們當然可以直接實現類,但當實現類不能滿足要求,要擴充套件需求,根據開閉原則你又不能修改實現類程式碼,這時你就用代理類。比如購買一輛車我們要對客戶進行一個購車款稽核,如果符合條件就買車,不符合要求我們就告知客戶購車款不足。

 @Override
    public void buyCar() {//實現為客戶買車
        int cash=customer.getCash();
        if(cash<100000){
            Log.e("buyCar","你的錢不夠買一輛車");
            return;
        }
        customer.buyCar();
    }

實現場景

Customer customer=new Customer();
customer.setCash(120000);
BuyCarProxy buyCarProxy=new BuyCarProxy(customer);
buyCarProxy.buyCar();

Customer customer1 =new Customer();
customer1.setCash(90000);
BuyCarProxy buyCarProxy1 =new BuyCarProxy(customer1);
buyCarProxy1.buyCar();

動態代理機制:

以上講的都是代理模式的靜態實現,所謂靜態代理就是自己要為要代理的類寫一個代理類,或者用工具為其生成的代理類,總之,就是程式執行前就已經存在的編譯好的代理類,這樣有時候會覺得非常麻煩,也導致非常的不靈活,相比靜態代理,動態代理具有更強的靈活性,因為它不用在我們設計實現的時候就指定某一個代理類來代理哪一個被代理物件,我們可以把這種指定延遲到程式執行時由JVM來實現

舉例:還是接著上面的例子

1.)首先我們要宣告一個動態代理類,實現InvocationHandler介面

public class DynamicProxy implements InvocationHandler {

    // 被代理類的例項
    Object obj;

    // 將被代理者的例項傳進動態代理類的建構函式中
    public DynamicProxy(Object obj) {
        this.obj = obj;
    }

    /**
     * 覆蓋InvocationHandler介面中的invoke()方法
     * 更重要的是,動態代理模式可以使得我們在不改變原來已有的程式碼結構
     * 的情況下,對原來的“真實方法”進行擴充套件、增強其功能,並且可以達到
     * 控制被代理物件的行為,下面的before、after就是我們可以進行特殊
     * 程式碼切入的擴充套件點了。
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        /*
         * before :doSomething();
         */
        Object result = method.invoke(this.obj, args);

        /*
         * after : doSomething();
         */
        return result;
    }
}

2.)具體實現

        //我們要代理的真實物件
        Customer customer = new Customer();
        //我們要代理哪個真實物件,就將該物件傳進去,最後是通過該真實物件來呼叫其方法的
        InvocationHandler handler = new DynamicProxy(customer);

        /*
         * 通過Proxy的newProxyInstance方法來建立我們的代理物件,我們來看看其三個引數
         * 第一個引數 handler.getClass().getClassLoader() ,我們這裡使用handler這個類的ClassLoader物件來載入我們的代理物件
         * 第二個引數customer.getClass().getInterfaces(),我們這裡為代理物件提供的介面是真實物件所實行的介面,表示我要代理的是該真實物件,這樣我就能呼叫這組介面中的方法了
         * 第三個引數handler, 我們這裡將這個代理物件關聯到了上方的 InvocationHandler 這個物件上
         */
        IBuyCar buyCar = (IBuyCar) Proxy.newProxyInstance(handler.getClass().getClassLoader(), customer.getClass().getInterfaces(), handler);
        buyCar.buyCar();

3.)動態代理好處

使用Java動態代理機制的好處:

1、減少程式設計的工作量:假如需要實現多種代理處理邏輯,只要寫多個代理處理器就可以了,無需每種方式都寫一個代理類。

2、系統擴充套件性和維護性增強,程式修改起來也方便多了(一般只要改代理處理器類就行了)。

總結:

   通過上面的應用例子我們學習了代理模式的具體使用場景。

相關推薦

Java設計模式代理模式Proxy

前言:       最近在研究Retrofit開源框架的時候,其主要核心程式碼是通過註解標示引數,動態代理模式實現具體介面,反射機制進行引數解析,最終實現傳送請求。其實之前在學習Xutils原始碼的時候,Xutils 的task也是通過代理模式來訪問的。為何要採用代理模式呢?有什麼好處呢?抱著這些疑問!今天

JAVA設計模式----------代理模式Proxy

這裡只是簡單的介紹下最基本的代理的使用。 代理,通俗點說 :就是一個人或者一個機構代表另一個人或者另一個機構採取行動。 在一些情況下,一個客戶不想或者不能夠直接引用一個物件,而代理物件可以在客戶 端和目標物件之前起到中介的作用。代理模式給某一個物件提供一個代理物件,並由代

設計模式 - 代理模式Proxy Pattern

ride proxy idt object catch 實例化 圖片 null 人在 代理模式:代理是一種常用的設計模式,其目的就是為其他對象提供一個代理以控制對某個對象的訪問。代理類負責為委托類預處理消息,過濾消息並轉發消息,以及進行消息被委托類執行後的後續處理。很多可以

java設計模式代理模式

images 缺點 封裝 增加 處理 其他 -1 target 目標 代理模式(Proxy)     代理模式的主要作用是為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不想或不能直接引用其他的對象,而代理對象可以在客戶端和目標之間起   到中介的模式。

設計模式代理模式Proxy2

技術分享 strong 流程 imp pla 遠程調用 height bst 速度 代理模式是為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用,其特征是代理類與委托類有同

java 設計模式代理模式(Proxy)

java 設計模式之代理模式(Proxy) 1. 概述 2.適用性 3.使用知識 4.核心思想 5. 類圖 6.dome 1. 概述 為其他物件提供一種代理以控制對這個物件的訪問

設計模式代理模式java實現

代理模式(Proxy):結構型的設計模式,目的是為其他物件提供一種代理以控制對這個物件的訪問。 即,它的思想是控制類或者介面對外的功能。 代理模式分為靜態代理模式和動態代理模式兩種。 在Spring中代理模式常見的是在AOP模組中,比如 JdkDynamicAopProxy

設計模式代理模式Proxy Pattern

應用場景 Proxy代理模式是一種結構型設計模式,主要解決的問題是:直接訪問物件時帶來的問題。 為了保持行為的一致性,代理類和委託類通常會實現相同的介面,所以在訪問者看來兩者並無區別。 代理類種類: 靜態:建立代理類再對其編譯,在程式執行前代理類的.class檔案就已

設計模式代理模式java

1、概念 為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。 2、UML類圖   3、java程式碼實現  抽象角色:表演介面(Act) public in

JAVA設計模式代理模式Proxy

wangking717 寫道 代理模式的作用是:為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個客戶不想或者不能直接引用另一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用。 或者在一系列功能模組中加入一些擴充套件的功能模組,那個時候就會用到面向切

JAVA設計模式 代理模式Proxy Pattern】

一、概述     給某一個物件提供一個代理,並由代理物件來完成對原物件的訪問。代理模式是一種物件結構型模式。 二、適用場景     當無法直接訪問某個物件或訪問某個物件存在困難時可以通過一個代理物件來間接訪問,為了保證客戶端使用的透明性,委託物件與代理物件需要實現相同

設計模式代理模式 Proxy Pattern

        代理模式:代理接活,被代理人幹活。主要是用了java的多型特性,定義一個藉口, 讓代理類和被代理類都實現該介面,關鍵在於在代理類的構造方法中引用被代理類 的構造方法。 介面: public interface Start {     public void sing();     public

研磨設計模式 代理模式Proxy2——跟著cc學設計系列

11.2  解決方案 11.2.1  代理模式來解決 用來解決上述問題的一個合理的解決方案就是代理模式。那麼什麼是代理模式呢? (1)代理模式定義   (2)應用代理模式來解決的思路 仔細分析上面的問題,一次性訪問多條資料,這個可能性是很難避免的,是客戶的需要。也就是說,

研磨設計模式 代理模式Proxy3——跟著cc學設計系列

11.3  模式講解 11.3.1  認識代理模式 (1)代理模式的功能 代理模式是通過建立一個代理物件,用這個代理物件去代表真實的物件,客戶端得到這個代理物件過後,對客戶端沒有什麼影響,就跟得到了真實物件一樣來使用。        當客戶端操作這個代理物件的時候,實際上功

研磨設計模式 代理模式Proxy1——跟著cc學設計系列

11.1  場景問題 11.1.1  訪問多條資料        考慮這樣一個實際應用:要一次性訪問多條資料。        這個功能的背景是這樣的;在一個HR(人力資源)應用專案中客戶提出,當選擇一個部門或是分公司的時候,要把這個部門或者分公司下的所有員工都顯示出來,而且

java設計模式代理模式 靜態&動態

  為其他物件提供一個代理控制對某個物件的訪問,代理類負責為委託類預處理訊息,過濾訊息並轉發訊息,以及進行訊息被委託類執行後的後續處理。 代理類和委託類要實現相同的介面,因為代理真正實現的還是委託類的方法。 使用場景:   如果需要委託類處理某一業務,就可以在代理類中統一處

java設計模式代理模式動態代理

  今天給大家分享的是java設計模式之代理模式中的動態代理模式。如有不足,敬請指正。   我們上次說到靜態代理使用一個代理類

大型Java進階專題設計模式代理模式

#代理模式 ##前言 又開始我的專題了,又停滯了一段時間了,加油繼續吧。都知道 SpringAOP 是用代理模式實現,到底是怎麼實現的?我們來一探究竟,並且自己模擬手寫還原部分細節。 ##代理模式的應用 在生活中,我們經常見到這樣的場景,如:租房中介、售票黃牛、婚介、經紀人、快遞、 事務代理、非侵入式日

java設計模式代理模式

單擊 [] 部分 空間 快遞公司 存儲 交互 idt encoding 【學習難度:★★★☆☆,使用頻率:★★★★☆】 代理模式是常用的結構型設計模式之一,當無法直接訪問某個對象或訪問某個對象存在困難時可以通過一個代理對象來間接訪問,為了保證客戶端使用的透明性,所訪問的真實

設計模式代理模式 Proxy

net rac style and static his public 分享 con 定義與模型 ‘ 應用場景和分類 代碼實現 staticProxy 靜態代理 public interface Star { /** * 面談