代理模式

代理模式

定義 : 爲其他對象提供一種代理以控制對這個對象的訪問。

代理模式的使用場景

當無法或不想直接訪問某個對象或訪問某個對象存在困難時可以通過一個代理對象來間接訪問,爲了保證
客戶端使用的透明性,委託對象與代理對象需要實現相同的接口。

靜態代理

來看一組例子  小明現在想買一輛車但是車的種類太多了小明對車也不是很瞭解 所以小明打算找個代理去買車。

//買車的接口

public interface IBuyCar {
    /**
     * 找車
     */
    void find();

    /**
     * 向4s店提交買車的想法
     */
    void submit();

    /**
     * 付錢
     */
    void pay();

    /**
     * 開回家
     */
    void drive();
}

//小明

public class CifzBuyCar implements IBuyCar {

    @Override
    public void find() {
        // TODO Auto-generated method stub
        System.out.println("我要買車,先去轉轉找車");
    }

    @Override
    public void submit() {
        // TODO Auto-generated method stub
        System.out.println("看好了找服務員說");
    }

    @Override
    public void pay() {
        // TODO Auto-generated method stub
        System.out.println("開始付錢");
    }

    @Override
    public void drive() {
        // TODO Auto-generated method stub
        System.out.println("付了錢,開回家");
    }

}  


//代理人  持有一個具體被代理者的引用

public class CarProxy implements IBuyCar {

private IBuyCar iBuyCar;

    /**
     * @param iBuyCar
     */
    public CarProxy(IBuyCar iBuyCar) {
        super();
        this.iBuyCar = iBuyCar;
    }

    @Override
    public void find() {
        // TODO Auto-generated method stub
        iBuyCar.find();
    }

    @Override
    public void submit() {
        // TODO Auto-generated method stub
        iBuyCar.submit();
    }

    @Override
    public void pay() {
        // TODO Auto-generated method stub
        iBuyCar.pay();
    }

    @Override
    public void drive() {
        // TODO Auto-generated method stub
        iBuyCar.drive();
    }

}   

//客戶端

public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //構造一個買車的人
        IBuyCar cifz = new CifzBuyCar();
        CarProxy proxy = new CarProxy(cifz);
        proxy.find();
        proxy.submit();
        proxy.pay();
        proxy.drive();
    }

}   

現在買車的代理流程就清晰了 但是現在有個問題  就是可以代理其他人嗎?答案是可以 只需要在定義一個

小紅什麼的 實現IBuyCar接口 

上述的代碼其實靜態代理 代理者的代碼有程序員自己或通過一些自動化工具生成固定的代碼 再對其進行編譯,也就是說
在我們的代碼運行前代理類的class編譯文件就已經存在。

而動態代理則與靜態代理相反,通過反射機制動態的生成代理者的對象,也就是說我們在code階段壓根就不需要知道代理水,代理
誰我們將會在執行階段決定。而java也給我們提供了一個便捷的動態代理接口InvocationHandler。

我們下面看一下動態代理該怎麼寫 還是以買車爲例

//動態代理類

/**
 * 動態代理類
 */
public class DynamicProxy implements InvocationHandler {

    private Object obj;

    /**
     * @param obj
     */
    public DynamicProxy(Object obj) {
        super();
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        Object result = method.invoke(obj, args);
        return result;
    }

}

//修改後的客戶端

public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //構造一個買車的人
        IBuyCar cifz = new CifzBuyCar();
        DynamicProxy proxy = new DynamicProxy(cifz);
        /**
         * 獲取被代理類 cifz的classloader
         */
        ClassLoader loader = cifz.getClass().getClassLoader();
        /**
         * 動態構造一個代理買車者
         */
        IBuyCar iBuyCar = (IBuyCar) Proxy.newProxyInstance(loader, new Class[] {IBuyCar.class}, proxy);
        iBuyCar.find();
        iBuyCar.submit();
        iBuyCar.pay();
        iBuyCar.drive();

    }

}

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