1. 程式人生 > >java常用設計模式9——代理模式

java常用設計模式9——代理模式

介紹:代理模式也稱為委託模式。
定義:為其它物件提供一種代理以控制對這個物件的訪問。

程式碼舉例:
山中有一個大王,大王有一個嘍囉,大王需要巡山來保證自己的地盤不被入侵,但是大王怎麼能自己去巡山呢?所以就要嘍囉代替大王來巡山。
我們用代理模式描述這個場景

//任務
public interface Tasks {
    /**
     * 需要執行的任務: 巡山
     */
    void PatrolTheMountain();
}
//大王
public class DaWang implements Tasks {
    //大王的嘍囉
    private Louluo louluo;
public DaWang(Louluo louluo) { this.louluo = louluo; } @Override public void PatrolTheMountain() { //大王不會自己去巡山,所以讓嘍囉代替自己去 louluo.PatrolTheMountain(); } } //嘍囉 public class Louluo implements Tasks { @Override public void PatrolTheMountain() { Log.
i("LHD", "大王叫我來巡山吶~我把人間轉一轉~"); } }

開始執行任務:

                //代理模式
                //構造一個嘍囉
                Louluo louluo = new Louluo();
                //嘍囉加入大王麾下
                DaWang daWang = new DaWang(louluo);
                //巡山
                daWang.PatrolTheMountain();

我們構造了一個嘍囉物件,並把這個物件交給大王,大王釋出巡山命令,而在大王類內部其實是呼叫了傳進來的嘍囉物件的巡山方法,所以真正執行巡山任務的是大王的代理小嘍囉。

執行結果:
proxy

經過大王和嘍囉的不懈努力,山頭越來越大,這個時候大王的嘍囉也越來越多,這個時候大王不會再思考該讓誰去巡山,而是用手一指,隨機選一個嘍囉去巡山。這種不需要知道真正執行者是誰的情景,我們可以使用動態代理模式。

首先需要一個支援動態代理模式的大王,也就是有很多小嘍囉的大王。
public class DynamicDaWang implements InvocationHandler {

    private Object object;//具體的嘍囉物件的引用

    public DynamicDaWang(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object, args);
        return result;
    }

}

可以看到,我們實現了InvocationHandler介面,並在invoke方法裡呼叫了具體的被代理的方法。這種寫法一般是固定的。
我們聲明瞭一個Object引用,這個引用將指向真正執行任務的類,也就是被代理類,而具體執行被代理類的方法則在invoke方法中執行。

開始執行任務:
                //動態代理
                //隨機選一個嘍囉
                Tasks louluo = new Louluo();
                //有很多嘍囉的大王
                DynamicDaWang proxy = new DynamicDaWang(louluo);
                //獲取嘍囉的ClassLoader
                ClassLoader loader = louluo.getClass().getClassLoader();
                //需要執行的任務
                Tasks tasks = (Tasks) Proxy.newProxyInstance(loader, new Class[]{Tasks.class}, proxy);
                //大王釋出命令
                tasks.PatrolTheMountain();

執行結果:
proxy

使用動態代理可以不用關心代理的到底是誰,只需要實現InvocationHandler介面即可。在具體執行任務的時候再使用反射機制動態的生成代理者的物件。
也就是說,動態代理的代理物件是在程式碼執行階段才決定的。

實際專案中的使用:

我們要實現一個功能,比如播放器功能,可以使用騰訊播放器也可以使用其它的播放器,那麼我們可以使用代理模式對播放器的通用功能做一個封裝,具體使用播放器功能的時候只調用代理物件的方法,這樣在替換播放器sdk的時候可以極大的減少程式碼的修改量。

以上就是代理模式的簡單介紹啦 (#^ . ^#)