按照代理的創建時期,代理類可以分爲兩種:
靜態:由程序員創建代理類或特定工具自動生成源代碼再對其編譯。在程序運行前代理類的.class文件就已經存在了。
動態:在程序運行時運用反射機制動態創建而成。
RealSubject:真實角色,實現接口的類
Proxy:代理角色,包含對真實角色RealSubject的引用,進而操作真實對象。
Subject : 接口,是對象和它的代理共用
的接口,讓RealSubject和Proxy具有一致性。
爲了保持行爲的一致性,代理類和委託類通常會實現相同的接口,所以在訪問者看來兩者沒有絲毫的區別。並且,代理對象在執行真實對象操作時,附加其他操作,相當於對真實對象進行封裝。通過代理類這中間一層,能有效控制對委託類對象的直接訪問,也可以很好地隱藏和保護委託類對象,同時也爲實施不同控制策略預留了空間,從而在設計上獲得了更大的靈活性。
靜態代理
package com.sz.demo;
public class TestStaticProxy {
//抽象接口
static interface Subject{
void sayHi();
void sayHello();
}
//真實角色
static class SubjectImpl implements Subject{
@Override
public void sayHi(){ //代理可以幫忙做的事
System.out.println("Hi");
}
@Override
public void sayHello(){
System.out.println("Hello");
}
}
//該角色的代理
static class SubjectImplProxy implements Subject{
private Subject target;
public SubjectImplProxy(Subject target){
this.target = target;
}
@Override
public void sayHi(){
System.out.println("say:");
target.sayHi();
}
@Override
public void sayHello(){
System.out.println("say:");
target.sayHello();
}
}
//測試
public static void main(String[] args){
Subject subject = new SubjectImpl();
Subject subjectProxy = new SubjectImplProxy(subject);
subjectProxy.sayHi();
subjectProxy.sayHello();
}
}
優點
- 代理使客戶端不需要知道實現類是什麼,怎麼做的,而客戶端只需知道代理即可(解耦合),對於客戶端代碼,可以應用工廠將它隱藏。
- 使用Proxy角色,使得耗時處理(生成實例)推遲。
- 在大型系統的初始化過程中,存在大量耗時處理,如果初始化暫時不會使用的功能,會使啓動時間延長,所以使用代理模式,先初始化需要使用的功能。
缺點
- 增加了代碼維護的複雜度:代理類和委託類實現了相同的接口,代理類通過委託類實現了相同的方法。這樣就出現了大量的代碼重複。如果接口增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。
- 靜態代理類只能爲特定的接口(Service)服務。如想要爲多個接口服務則需要建立很多個代理類。靜態代理在程序規模稍大時就無法勝任了。