代理模式(靜態/動態)

什麼叫做代理模式?

代理模式在設計模式中的定義就是:爲其他對象提供一種代理來控制這個對象的訪問。就是在一些客戶不想或者不能直接引用一個對象,而代理對象可以在客戶和目標之間起到一箇中介作用,去掉客戶不能看到的內容和服務或者增添客戶需要的額外服務。即通過代理對象訪問目標對象。

代理模式分爲靜態代理和動態代理!(Spring AOP的底層就是代理模式)

1:靜態代理:

例如:一個人需要租房子(客戶)想要租房子,而恰好有一位房東(目標對象/真實角色)需要出租自己的房子。但是房東只是想把房子租出去,至於租給誰怎麼租合同怎麼籤這些繁瑣的事情他不想去管理,這個時候他就可以找一個房屋中介(代理角色),讓中介幫他把房子租出。然後房東跟中介都有一個共同點就是要把房子租出去(接口)。這個時候需要租房子的人就可以直接去找中介租房子。而不需要去找房東。這種方式就叫做靜態代理。

package com.lrx.demo01;
//租房接口
public interface Rent {
    public void rent();
}
package com.lrx.demo01;
//真實角色(房東)
public class Host implements Rent {
    public void rent() {
        System.out.println("房東要出租房子!");
    }
}

package com.lrx.demo01;
//代理角色(中介)
public class Proxy implements Rent {
    private Host host;

    public Proxy(){

    };
    public Proxy(Host host) {
        this.host = host;
    };

    public void rent() {
        host.rent();
        seeHouse();
        signContract();
        rentCollection();
    }
    //看房
    public void seeHouse(){
        System.out.println("中介帶你看房子!");
    }
    //籤合同
    public void signContract(){
        System.out.println("中介和你籤合同!");
    }
    //收房租
    public void rentCollection(){
        System.out.println("中介收取你的房租");
    }
}
package com.lrx.demo01;
//客戶(租客)
public class Client {
    public static void main(String[] args) {
        Host host=new Host();
        //直接把房東host(真實角色)的房子丟給代理角色proxy,讓他去出租。
        Proxy proxy=new Proxy(host);
        proxy.rent();
    }
}

輸出結果爲:

房東要出租房子!
中介帶你看房子!
中介和你籤合同!
中介收取你的房租

角色分析:
抽象角色:一般使用接口和抽象類來解決。
真實角色:被代理的角色
代理角色:代理真實角色,代理真實角色後,我們一般會做一些附屬操作
客戶:訪問代理對象的人
代理模式的好處:
可以使真實角色的操作更加純粹!不用去關注一些公共的業務
公共業務就交給了代理角色!實現了業務的分工
公共業務發生擴展的時候,方便集中管理
缺點:
一個真實角色就會產生一個代理角色;代碼量會翻倍,開發效率會變低(動態代理可解決)

2:動態代理:

動態代理和靜態代理角色一樣
動態代理類(代理角色類)是動態生成的,不是我們手動編寫好的類。

動態代理分爲兩大類:基於接口的動態代理和基於類的動態代理
基於接口—JDK動態代理(我們在這裏使用):
基於類:cglib
java字節碼實現:javassist
需要了解兩個類:
Proxy:代理
InvocationHandler:調用處理程序接口

package com.lrx.demo02;
//租房接口
public interface Rent {
    public void rent();
}
package com.lrx.demo02;

import com.lrx.demo02.Rent;

//真實角色(房東)
public class Host implements Rent{
    public void rent() {
        System.out.println("房東要出租房子!");
    }
}
//我們會用這個類自動生成代理類
public class ProxyInvocationHandler  implements InvocationHandler {
    //被代理的接口
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }

    //生成得到代理類
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    };
    //處理代理實例,並返回結果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        //動態代理的本質就是使用反射機制實現
        Object result=method.invoke(rent,args);
        rentCollection();
        return result;
    }

    public void seeHouse(){
        System.out.println("中介帶你看房子!");
    }

    public void rentCollection(){
        System.out.println("收房租!");
    }
}

package com.lrx.demo02;

public class Client {
    public static void main(String[] args) {
        //真實角色描寫
        Host host=new Host();
        //調用程序
        ProxyInvocationHandler pih=new ProxyInvocationHandler();
        //通過調用程序處理角色來處理我們要調用的接口對象
        pih.setRent(host);
        Rent proxy= (Rent) pih.getProxy();
        proxy.rent();
    }
}

輸出結果:

中介帶你看房子!
房東要出租房子!
收房租!

一個動態代理類代理的是一個接口,一般就是對應的一類業務,一個動態代理類可以代理多個類!只要是實現了同一個接口即可

發佈了9 篇原創文章 · 獲贊 6 · 訪問量 634
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章