天天看點

《設計模式修煉真經》08 — 代理模式

1、定義

代理模式的定義:為其他對象提供一種代理以控制對這個對象的通路;

代理模式也叫做委托模式,是一種使用頻率非常高的設計模式;在生活中有一種職業可以非常好的展現代理模式 — 中介;

2、類圖

代理模式的通用類圖如下:

《設計模式修煉真經》08 — 代理模式

代理模式的結構很簡單,主要是通過定義一個繼承抽象主題的代理來包含真實主題,進而實作對真實主題的通路控制,各部分組成如下:

  • 抽象主題(Subject)類:可以是抽象類也可以是接口,是一個最普通的業務類型定義,無特殊要求;
  • 真實主題(Real Subject)類:實作了抽象主題中的具體業務,是代理對象所代表的真實對象,是最終要引用的對象;
  • 代理(Proxy)類:提供了與真實主題相同的接口,其内部含有對真實主題的引用,它可以通路、控制或擴充真實主題的功能。

3、代碼實作

抽象主題 的Java代碼實作如下:

interface Subject {
    void Request();
}      

真實主題 的Java代碼實作如下:

class RealSubject implements Subject {
    public void Request() {
        System.out.println("通路真實主題方法...");
    }
}      

代理類 的Java代碼實作如下:

class Proxy implements Subject {
    private RealSubject realSubject;
    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.Request();
        postRequest();
    }
    public void preRequest() {
        System.out.println("通路真實主題之前的預處理。");
    }
    public void postRequest() {
        System.out.println("通路真實主題之後的後續處理。");
    }
}      

4、特點

優點:

1、職責清晰,降低了系統的耦合度;

真實主題就是實際的業務邏輯,無需關心其他業務邏輯,通過代理完成整個完整的功能,軟體功能劃分簡潔清晰。

2、高擴充性;

代理對象可以擴充目标對象的功能;

3、保護敏感對象;

在使用者與目标對象之間起到一個中介作用和保護目标對象的作用;

缺點:

1、會造成系統設計中類的數量增加;

2、代理對象容易成為性能瓶頸;

3、增加了系統的複雜度;

5、适用場景

當無法或不想直接引用某個對象或通路某個對象存在困難時,可以通過代理對象來間接通路;

使用代理模式主要有兩個目的:一是保護目标對象,二是增強目标對象。

6、動态代理

上述的代理模式,我們需要自己實作代理類,這是方式叫做靜态代理;

靜态代理存在兩個缺點:

  • 真實主題與代理主題一一對應,增加真實主題也要增加代理;
  • 設計代理類之前真實主題必須事先存在,缺少靈活性;

采用動态代理模式可以解決以上問題;動态代理是在實作階段不用關心代理誰,而在運作階段才指定代理哪一個對象。

而在Java 中,JDK幫我們封裝好了動态代理相關的類,可以非常輕松的實作動态代理;

6.1 Java中的動态代理類

Java動态代理類位于java.lang.reflect包下,主要涉及到以下一個接口和一個類:

1、InvocationHandler 接口

該接口中僅定義了一個方法

public object invoke(Object obj,Method method, Object[] args)      

參數obj 指 被代理類,method是 被代理的方法,args為該方法的參數數組;

2、Proxy 動态代理類

該類即為動态代理類,其中主要包含以下内容:

//構造函數,用于給内部的InvocationHandler指派
protected Proxy(InvocationHandler h)

//獲得一個代理類,其中loader是類裝載器,interfaces是真實類所擁有接口的數組
static Class getProxyClass (ClassLoaderloader, Class[] interfaces)

//傳回被代理類的一個執行個體,傳回後的Object可以當作被代理類使用
static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)      

6.2 JDK動态代理機制的使用

主要分為兩個步驟:

第一步:實作InvocationHandler

public class InvocationHandlerImpl implements InvocationHandler
{
    //要代理的真實對象
    private Object subject;
 
    //構造方法,給我們要代理的真實對象賦初值
    public InvocationHandlerImpl(Object subject)
    {
        this.subject = subject;
    }
 
    /**
     * 集中處理動态代理類上的所有方法調用。
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        //在代理真實對象前可以添加一些自己的操作
        ....
        //執行要調用的方法
        Object returnValue = method.invoke(subject, args);
        //在代理真實對象後我們也可以添加一些自己的操作
        ....
        return returnValue;
    }
}      

第二步:調用Proxy.newProxyInstance生成動态代理類執行個體

public class DynamicProxyDemo
{
    public static void main(String[] args)
    {
        //代理的真實對象
        Subject realSubject = new RealSubject();
        
        //建立InvocationHandlerImpl對象
        InvocationHandler handler = new InvocationHandlerImpl(realSubject);
 
        //生成動态代理類執行個體
        ClassLoader loader = realSubject.getClass().getClassLoader();
        Class[] interfaces = realSubject.getClass().getInterfaces();
        Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);
         //使用動态代理類執行個體
         subject.doSomething();
    }
}      

6.3 JDK動态代理機制的原理

此部分不是本文的重點,感興趣的同學可以自行閱讀源碼,大體上可以分為四步驟:

  1. 通過實作 InvocationHandler 接口建立自己的調用處理器;
  2. 通過為 Proxy 類指定 ClassLoader 對象和一組 interface 來建立動态代理類;
  3. 通過反射機制獲得動态代理類的構造函數,其唯一參數類型是調用處理器接口類型;
  4. 通過構造函數建立動态代理類執行個體,構造時調用處理器對象作為參數被傳入。

本文參考了:Java JDK 動态代理(AOP)使用及實作原理分析

我的視訊課

下面是我錄制的一些視訊課,歡迎大家圍觀~《設計模式修煉真經》​ 設計模式是一套被反複使用的、多數人知曉的、經過分類編目的、代碼設計經驗的總結,代表了最佳的實踐,通常被有經驗的面向對象的軟體開發人員所采用。 本套課程深入介紹了經典的23種設計模式,并加入了自己的感悟,希望大家能夠徹底掌握設計模式,寫出最好的代碼,達到無招勝有招的境界,最終超越這23種設計模式。

《徹底搞定JVM》​ JVM是Java中重要的也是較難了解的内容; 面試者對JVM的了解程度某種程度上反映了面試者技術深度,是以JVM也是面試時經常考察的内容; 本課程從JVM運作流程、資料運作時區域組成部分、類加載機制、垃圾回收機制、記憶體模型、常見面試題講解等角度出發,幫你徹底搞定JVM,拿下心儀Offer;

《Android性能優化參考》 本課程包含了Android中的App啟動優化、UI優化、記憶體優化、圖檔優化、耗電量等常見的性能優化場景,通過學習此課程,你将對整個Android性能優化體系有清晰的認識。

性能優化作為Android進階開發的必備技能,也是大廠面試必考的題目,是展現一個人技術深度最好的試金石。

《面試之排序算法》 排序算法是我們面試被問到最多的基礎算法,本課程詳細介紹了七種排序算法,包括插入排序、選擇排序、冒泡排序、謝爾排序、快速排序、堆積排序和二路并歸排序。每種算法都詳細介紹了核心思想、詳細步驟、時間複雜度和代碼實作,希望幫助大家深入了解排序算法,搞定面試!

《Android HyBrid App開發實戰》 本課程為Android HyBrid App開發實戰課程,由淺入深,從三種App的曆史和特點開始,介紹了Android WebView的使用、Java和JS互動的原生方式、著名的WebView安全漏洞、JSBridge的原理和使用,最後通過一個網上商城的實戰綜合全部内容,讓同學們掌握并深入了解Android HyBrid App開發。

《AI導論》​ 介紹人工智能AI的誕生曆史和到現在為止的不同發展階段;介紹了AI領域中常見的名詞概念和其關系,包括機器學習、深度學習、神經網絡結構搜尋 NAS、生成對抗網絡 GAN等;最後對AI發展做出展望。 本課程屬于導論課程,旨在幫助同學們從宏觀層面把握AI,建立AI的知識體系。

《Java注解精講》​ 本課程詳細介紹了Java中的注解機制,包括注解的定義和分類,注解的使用和自定義,注解的源碼和架構分析; 本課程語言簡單凝練,視訊短小精悍,讓你一次徹底搞懂Java注解!

《Java反射精講》​ 反射是Java中重要的也是較難了解的内容;

本課程從反射的定義、作用、原理和使用出發,全方位幫你徹底搞定反射;

您的點贊是我前進的動力~