代理模式

代理模式:

爲一個對象提供一種代理,以控制對這個對象的訪問。分爲靜態代理和動態代理。

什麼時候要用?

(1)當我們想要隱藏某個類時,可以爲其提供代理類
(2)當一個類需要對不同的調用者提供不同的調用權限時,可以使用代理類來實現
(3)當我們要擴展某個類的某個功能時,可以使用代理模式,在代理類中進行簡單擴展
(4)spring的aop就是使用了動態代理。

優點

(1)將代理對象與真實被調用的目標對象分離,降低了系統的耦合度
(2)保護目標對象
(3)增強目標對象

缺點

(1)會造成系統設計中類的數目增加
(2)在客戶端和目標對象之間增加了代理對象,會造成請求的處理速度變慢
(3)增加系統的複雜度

原理

使用一個代理將對象包裝起來,然後用該代理對象取代原始對象任何對原始對象的調用都要通過代理。代理對象決定是否以及何時將方法調用轉到原始對象上。

分類

靜態代理

特點
靜態代理的代理類和目標對象類都是在編譯期確定下來的,所以不利於程序的擴展。而且,每一個代理類只能爲一個接口服務,這樣一來程序開發中必然產生過多的代理。

代碼實現
過程大致是這樣的:
(1)被代理類(actor)出現。
(2)代理類(agent)出現,並與被代理類產生關係。(通過實現同一個接口產生聯繫)
(3)代理類執行方法。(判斷是否接受代言的方法)

package com.revision.DesignMethod.proxyPattern;

interface Work{
    void decide();
}

class Actor implements Work{
    @Override
    public void decide() {
        System.out.println("我要聽從代理人的意見!請和我的代理人交流!");
    }
}

class Agent implements Work{

    Actor a = null;

    public Agent(Actor a){
        this.a = a;
    }

    @Override
    public void decide() {
        System.out.println("你好,我是代理!");
        a.decide();
    }
}

public class StaticProxyPattern {
    public static void main(String[] args) {
        //先new一個被代理對象
        Actor actor = new Actor();
        //代理類出現,並於被代理人產生關係
        Agent agent = new Agent(actor);
        //代理人替被代理人執行方法
        agent.decide();
    }
}

動態代理

特點
動態代理是在程序運行時根據需要動態創建目標類的代理對象,客戶可通過代理類來調用其它對象的方法。動態代理加入了反射,肯定會比靜態代理先進一點。

代碼實現
執行思路和靜態代理是一樣的:
(1)被代理類出現。
(2)代理類出現,並與被代理類建立關聯。
(3)代理類執行方法。(main函數中調用代理類的方法,代理類處調用被代理類的方法)

package com.revision.DesignMethod.proxyPattern;

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

//動態代理的使用
interface Subject{
    void action();
}
//被代理類
class RealSubject implements Subject{
    @Override
    public void action() {
        System.out.println("被代理類!");
    }
}

//代理類
class MyInvocationHandler implements InvocationHandler {

    Object obj;
    //給被代理對象進行實例化,返回一個代理類的對象
    public Object blind(Object obj){
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),this);
    }

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

public class DynamicProxyPattern {
    public static void main(String[] args) {
        RealSubject real = new RealSubject();
        MyInvocationHandler handler = new MyInvocationHandler();
        Object obj = handler.blind(real);
        Subject sub = (Subject)obj;
        sub.action();
    }
}

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