代理模式(Proxy)

一、概念java

代理模式爲其餘對象提供一個代理以控制對這個對象的訪問,屬於結構性模式。從代碼的角度來分,代理能夠分爲兩種:一種是靜態代理,另外一種是動態代理。 靜態代理就是在程序運行前就已經存在代理類的字節碼文件,代理類和委託類的關係在運行前就肯定了。 動態代理類的源碼是在程序運行期間根據反射等機制動態的生成,因此不存在代理類的字節碼文件。代理類和委託類的關係是在程序運行時肯定。 bash

圖片

二、模式結構ide

  • Subject(抽象主題類):接口或者抽象類,聲明真實主題與代理的共同接口方法。
  • RealSubject(真實主題類):也叫作被代理類或被委託類,定義了代理所表示的真實對象,負責具體業務邏輯的執行,客戶端能夠經過代理類間接的調用真實主題類的方法。
  • Proxy(代理類):也叫委託類,持有對真實主題類的引用,在其所實現的接口方法中調用真實主題類中相應的接口方法執行。

三、使用場景優化

  • 當一個對象不能或者不想直接訪問另外一個對象時,能夠經過一個代理對象來間接訪問
  • 被訪問的對象不想暴露所有內容時,能夠經過代理去掉不想被訪問的內容
  • 一個消耗資源較少的對象來表明一個消耗資源較多的對象,從而下降系統開銷、縮短運行時間時

四、優缺點ui

優勢:this

  • 協調調用者和被調用者,下降了系統的耦合度
  • 代理對象做爲客戶端和目標對象之間的中介,起到了保護目標對象的做用
  • 以一個小對象代理一個大對象,達到優化系統提升運行速度的目的

缺點:spa

  • 調用者和真實主題之間增長了代理對象,所以可能會形成請求的處理速度變慢。
  • 實現代理模式須要額外的工做,從而增長了系統實現的複雜度

五、實例代理

靜態實例code

public interface IUserDao {
    int save();
}
複製代碼
public class UserDao implements IUserDao {

    @Override
    public int save() {
        return 0;
    }
}
複製代碼
public class UserDaoProxy implements IUserDao {

    //接收保存目標對象
    private IUserDao target;

    public UserDaoProxy(IUserDao target) {
        this.target = target;
    }

    @Override
    public int save() {
        return target.save();
    }
}
複製代碼

動態實例:cdn

仍是使用靜態代理的IUserDao和UserDao 類,改造UserDaoProxy 類,利用java的newProxyInstance動態生成實例。

public class UserDaoProxy {

    //維護一個目標對象
    private Object target;

    public UserDaoProxy(Object target) {
        this.target = target;
    }

    //給目標對象生成代理對象
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //運用反射執行目標對象方法
                        Object returnValue = method.invoke(target, args);
                        return returnValue;
                    }
                }
        );
    }
}
複製代碼
public static void main(String[] args) {
    // 目標對象
    IUserDao target = new UserDao();
    System.out.println(target.getClass());
    // 給目標對象,建立代理對象
    IUserDao proxy = (IUserDao) new UserDaoProxy(target).getProxyInstance();
    proxy.save();
}
複製代碼
相關文章
相關標籤/搜索