《一天一模式》— 代理模式

1、代理模式的概念

代理(Proxy)是一種設計模式,提供了間接對目標對象進行訪問的方式。即經過代理對象訪問目標對象,這樣作的好處是,能夠在目標對象實現的功能上,增長額外的功能補充,即擴展目標對象的功能.。java

2、何時使用代理模式

代理類主要負責爲委託類作消息預處理、消息過濾。把消息轉發給委託類,以及過後對返回結果的處理等。數據庫

代理類自己並不真正實現服務,而是經過調用委託類的相關方法,來提供特定的服務。真正的業務功能仍是由委託類來實現,可是能夠在業務功能執行的先後加入一些公共的服務。編程

例如咱們想給項目加入緩存、日誌這些功能,咱們就可使用代理類來完成,而不必打開已經封裝好的委託類。設計模式

3、怎麼使用代理模式

以上面的例子來講,加入系統原有一個查詢用戶信息的功能,因爲項目迭代,要在查詢用戶信息時,先讀取緩存,緩存中沒有在從庫中查詢。緩存

這個場景就可使用代理模式來實現,不須要修改原有的從庫中查詢的方法,只須要加入代理模式就能夠解決。框架

下面來看下用Java方式實現代理模式要怎麼作。測試

3.1 實現方式

// 用戶服務接口
public interface UserService {

    void findById();

}

// 查詢用戶的實現類
public class UserServiceImpl implements UserService {

    public void findById() {
        System.out.println("從數據庫查詢用戶信息。");
    }
}

// 代理類
public class UserProxy implements UserService {

    // 真正處理業務的對象
    private UserService userService;

    public UserProxy(UserService userService) {
        this.userService = userService;
    }

    // 代理方法
    public void findById() {
        System.out.println("從緩存中查詢用戶信息。");
        System.out.println("緩存中未查詢到用戶信息。");
        userService.findById();
    }

}

public class Client {

    public static void main(String[] args) {
        // 使用代理模式以前,已經封裝好方法,直接從數據庫中查詢。
        UserService userService = new UserServiceImpl();
        userService.findById();
        System.out.println();
        // 使用代理模式加入從緩存查詢
        UserService userProxy = new UserProxy(userService);
        userProxy.findById();

    }

}

// 輸出:
//從數據庫查詢用戶信息。
//
//從緩存中查詢用戶信息。
//緩存中未查詢到用戶信息。
//從數據庫查詢用戶信息。

代理模式如上面的作法,先建立代理類並實現被代理類的接口,而後在代理類中定義一個被代理類的實例,實例化時注入進來。this

關鍵在於代理方法,代理方法中調用被代理對象,能夠在調用前,調用後加入代理類想要的業務,就是作法就是代理模式。spa

3.2 代理模式的好處

  • 職責清晰:具體角色是實現具體的業務邏輯,不用關心其餘非本職責的事務,經過後期的代理完成一件事務,代碼清晰。在某些狀況下,一個客戶類不想或者不能直接引用一個委託對象,而代理類對象能夠在客戶類和委託對象之間起到中介的做用,其特徵是代理類和委託類實現相同的接口。
  • 高擴展性:具體主題角色隨時會發生變化,可是隻要實現了接口,接口不變,代理類就能夠不作任何修改繼續使用,符合「開閉原則」。

3.3 代理模式的幾種類型

Java中實現代理模式可分爲三種:設計

  • 靜態代理(上面的例子): 在使用靜態代理時,被代理對象與代理對象須要一塊兒實現相同的接口或者是繼承相同父類,所以要定義一個接口或抽象類。這種作法簡單直接,可讀性高;
  • 動態代理:動態代理的主要特色就是可以在程序運行時JVM才爲被代理對象生成代理對象。常說的動態代理也叫作JDK代理也是一種接口代理,JDK中生成代理對象的代理類就是Proxy,所在包是java.lang.reflect;
  • Cglib代理:Cglib代理也叫做子類代理,是在內存中構建一個子類對象從而實現對目標對象功能的擴展,使用這種代理技術無需實現接口;

幾種代理技術就不在設計模式中詳細說明了,會另外寫一篇調研代理的博客文章。

4、總結

業務上,當須要在調用某方法以前或以後進行相對應的處理,但又不想或無條件去修改要調用的方法,一般是不想,首先是要符合開閉原則,其次是在不修改原來的代碼,能夠減小測試範圍。這種情形下,很是適合使用代理模式。

代理模式使用的很是普遍,尤爲其中的動態代理技術,不少開源開發框架都在應用。特別在AOP編程模式下。

好比使用Spring的AOP,就是使用動態代理和Cglib代理來實現的。在使用AOP框架時,須要關注幾個名詞:

  • 切面(Aspect)

  • 切入點(JointPoint)

  • 通知(Advice)

  • 織入(Weave)

在此不對這些作過多說明了,相關信息能夠搜索AOP編程。

以上就是我對代理模式的一些理解,有不足之處請你們指出,謝謝。

相關文章
相關標籤/搜索