1. 程式人生 > >靜態代理與動態代理

靜態代理與動態代理

Proxy代理模式是一種結構型設計模式,主要解決的問題是:在直接訪問物件時帶來的問題

代理是一種常用的設計模式,其目的就是為其他物件提供一個代理以控制對某個物件的訪問。代理類負責為委託類預處理訊息,過濾訊息並轉發訊息,以及進行訊息被委託類執行後的後續處理。

比如你要買或賣房子,找個中介來幫你進行買賣,中介如何操作你並不關心,而你關心的是最終的結果,房子是否買賣成功,中間過程有中介來處理。這裡的中介就像我們理解的代理模式一樣。我們不直接進行買賣,而是通過中介買賣。我們不直接訪問某個物件,而是訪問其代理物件。

為了保持行為的一致性,代理類和委託類通常會實現相同的介面,所以在訪問者看來兩者沒有絲毫的區別。通過代理類這中間一層,能有效控制對委託類物件的直接訪問,也可以很好地隱藏和保護委託類物件,同時也為實施不同控制策略預留了空間,從而在設計上獲得了更大的靈活性。更通俗的說,代理解決的問題當兩個類需要通訊時,引入第三方代理類,將兩個類的關係解耦,讓我們只瞭解代理類即可,而且代理的出現還可以讓我們完成與另一個類之間的關係的統一管理,但是切記,代理類和委託類要實現相同的介面,因為代理真正呼叫的還是委託類的方法。

使用場合舉例:如果需要委託類處理某一業務,那麼我們就可以先在代理類中統一處理然後再呼叫具體實現類按照代理的建立時期,代理類可以分為兩種:

靜態:由程式設計師建立代理類或特定工具自動生成原始碼再對其編譯。在程式執行前代理類的.class檔案就已經存在了。

動態:在程式執行時運用反射機制動態建立而成。

靜態代理

靜態代理

模式中包含的角色及其職責

Subject:抽象主題角色,抽象主題類可以是抽象類,也可以是介面,是一個最普通的業務型別定義,無特殊要求。

RealSubject:具體主題角色,也叫被委託角色、被代理角色。是業務邏輯的具體執行者。

Proxy:代理主題角色,也叫委託類、代理類。它把所有抽象主題類定義的方法給具體主題角色實現,並且在具體主題角色處理完畢前後做預處理和善後工作。(最簡單的比如列印日誌):

//抽象主題,定義主要功能:
public interface Subject {
	public void operate();
}
//具體主題實現 Subject介面
public class RealSubject implements Subject {
	@Override
	public void operate(){
		System.out.println("realsubject operatestarted......");
		  }
}
//靜態代理物件
public class StaticProxy implements Subject {
	private Subject subject;
	//構造器注入
	StaticProxy(Subject subject){
	this.subject = subject;
	  }
	public void operate(){
		//日誌
			System.out.println("before operate......");
	        subject.operate();
	        System.out.println("after operate......");
	  }
}
public class ClientTest {

	//客戶測試
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 Subject subject = new RealSubject();  
	     StaticProxy proxy = new StaticProxy(subject);  
	     proxy.operate();
	}
}

優點:

代理使客戶端不需要知道實現類怎麼做的(不知道方法),而客戶端只需知道代理的方法即可(解耦合)

缺點:

1)代理類和委託類實現了相同的介面,代理類通過委託類實現了相同的方法。這樣就出現了大量的程式碼重複。如果介面增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了程式碼維護的複雜度。

2)代理物件只服務於一種型別的物件,如果要服務多型別的物件。勢必要為每一種物件都進行代理,靜態代理在程式規模稍大時就無法勝任了。如上的程式碼是隻為Realsubject類的訪問提供了代理,但是如果還要為其他類如Realsubject2類提供代理的話,就需要我們再次新增代理Realsubject2的代理類。

動態代理