代理模式的不同實現

代理模式

在有些情況下,一個客戶不能或者不想直接訪問另一個對象,這時需要找一箇中介幫忙完成某項任務,這個中介就是代理對象。例如,購買火車票不一定要去火車站買,可以通過 12306 網站或者去火車票代售點買。又如找女朋友、找保姆、找工作等都可以通過找中介完成。

在軟件設計中,使用代理模式的例子也很多,例如,要訪問的遠程對象比較大(如視頻或大圖像等),其下載要花很多時間。還有因爲安全原因需要屏蔽客戶端直接訪問真實對象,如某單位的內部數據庫等。
在這裏插入圖片描述 代理模式的結構圖

下面將通過一個案例來描述代理模式,個人理解,大佬繞路
案例引入:一個人惹上官司,準備上訴,剛開始通過自己的努力述說官司的原因和對方和談但以失敗告終,後來請了一個律師來幫自己,律師通過法律條文和到得宣講來打官司。上述的律師就是該人的一個代理,他們都有想對方陳述的方法,但律師的陳述是對該人陳述方法的增強,該代理代替本體執行和本體相同的方法,同時擴充該人陳述方法的能力,是對方法的增強。
下面通過代碼層面實現。
代碼層面:該人與該律師有相同的功能,實現相同的接口,代理依賴本體,沒有本體,代理也將沒有意義。
##靜態代理

package Proxy.delete;

public class Proxy {
}

interface Speaker{
    public void speak();
}

class LJW implements Speaker{

    @Override
    public void speak() {
        System.out.println("說明官司原因");
    }
}

class LJWProxy implements Speaker{

    @Override
    public void speak() {
        System.out.println("動用法律條文");
        new LJW().speak();
        System.out.println("道德層面述說");
    }
}

class Demo{
    public static void main(String[] args) {
        //靜態代理,編譯期就要將代理類寫好,如果不同的人就要寫不同的代理
        new LJWProxy().speak();
    }
}

##靜態代理,代理類在編譯時期就編譯好了,不足就是如果多個人就要寫多個不同的代理類。JDK提供了一系列代理類的接口,方便動態創建代理,更抽象,將代理實現類的創建從編譯期提升到了運行期,動態的根據不同的本體生成代理。

package Proxy.delete;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {
}

interface Speaker{
    public void speak();
}

class LJW implements Speaker{

    @Override
    public void speak() {
        System.out.println("說明官司原因");
    }
}

class LJWProxy implements InvocationHandler{

    private Object obj;

    public LJWProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("speak".equals(method.getName())){
            System.out.println("動用法律條文");
            method.invoke(obj,args);
            System.out.println("道德層面述說");
        }
        return null;
    }
}

class Demo{
    public static void main(String[] args) {
        LJWProxy ljwProxy = new LJWProxy(new LJW());
        Speaker speaker = (Speaker) Proxy.newProxyInstance(Demo.class.getClassLoader(), new Class[]{Speaker.class}, ljwProxy);
        speaker.speak();
    }
}

##上述代理中,本體必須實現接口,如果不實現接口,那麼就要用CGLib動態實現代理,導入cglib jar包

package Proxy.delete;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {
}
class LJW{
    public void speak(){
        System.out.println("說明官司原因");
    }
}

class LJWProxy implements MethodInterceptor{

    private Object obj;

    public LJWProxy(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if("speak".equals(method.getName())){
            System.out.println("用法律條文");
            method.invoke(obj,args);
            System.out.println("道德角度,打人不對");
        }
        return null;
    }
}

class Demo{
    public static void main(String[] args) {

        LJWProxy ljwProxy = new LJWProxy(new LJW());
        LJW ljw = (LJW) Enhancer.create(LJW.class, ljwProxy);
        ljw.speak();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章