1. 程式人生 > >設計模式學習--------12.代理模式學習

設計模式學習--------12.代理模式學習

送禮物 遠程代理 查看 靜態 福爾摩斯 log cat eas and

場景:

? ? ?福爾摩斯一直想送禮物給花生,可是羞於直接贈送,於是想到讓房東太太去幫忙送禮物.編程怎樣實現呢?

定義:

? ? ? 為其它對象提供一種代理以控制對這個對象的訪問。

角色:

Proxy:代理對象.有下列功能:

實現與詳細的目標對象一樣的接口,這樣就能夠使用代理來取代詳細的目標對象。

持有一個詳細目標對象的引用,能夠在須要時調用詳細的目標對象。

能夠控制對目標對象的訪問,並能夠負責創建和刪除它。

package com.kris.study;

public class Proxy implements Subject {

	private RealSubject realSubject = null;
	
	public Proxy(RealSubject realSubject){
		this.realSubject = realSubject;
	}
	
	@Override
	public void request() {
		System.out.println("代理之前做一些操作。。。。。。");
		realSubject.request();
		System.out.println("代理之後做一些操作。

。。。

。"); } }


Subject:目標接口

package com.kris.study;

public interface Subject {
    public void request();
}

RealSubject:詳細的目標對象,被代理的對象
package com.kris.study;

public class RealSubject implements Subject {

	@Override
	public void request() {
       //運行詳細的功能處理
	}

}

以下用代理模式實現場景。

package com.kris.study;

public interface SendGift {
    public void send();
}

package com.kris.study;

public class Holmes implements SendGift {

	@Override
	public void send() {
		System.out.println("送禮物給花生---來自福爾摩斯");
	}

}

package com.kris.study;

public class FangDongTaiTai implements SendGift {

	private Holmes holmes = null;
	
	public FangDongTaiTai(Holmes holmes){
		this.holmes = holmes;
	}

	@Override
	public void send() {
		System.out.println("親愛的花生,老福讓我給你帶個東西");
		holmes.send();
	}
	
}

package com.kris.study;

public class Client {
   public static void main(String[] args) {
	   Holmes holmes = new Holmes();
	   SendGift sendGift = new FangDongTaiTai(holmes);
	   sendGift.send();
   }
}

上面講的都是靜態代理,JAVA中提供了一套動態代理的機制,更加靈活。眼下JAVA的動態代理僅僅支持接口,若要實現類的代理,能夠使用cglib.

步驟:

1. ?創建一個實現接口InvocationHandler的類,它必須實現invoke方法。

2. ?創建被代理的類以及接口

3. ?通過Proxy的靜態方法new ProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

創建一個代理,這個代理不管運行什麽方法都會轉到Handler中的invoke方法去調用.

4. ?通過代理調用方法


上面第一步中的invoke方法參數說明

pubilc Object invoke(Object obj,Method method,Object[] args)

obj:代理類

method:被代理的方法

args:方法的參數


動態代理實現場景:

上面的SendGift接口和Holmes類都沒變化,如今把房東太太的實現變更為實現InvocationHandler

package com.kris.study;

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

public class FangDongTaiTai implements InvocationHandler {

	private SendGift holmes = null;
	
	public SendGift bindObject(Holmes holmes){
		this.holmes = holmes;
		SendGift sendProxy = (SendGift) Proxy.newProxyInstance(holmes.getClass().getClassLoader(),
				holmes.getClass().getInterfaces(), this);
		return sendProxy;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("親愛的花生,這是大福給你的");
		return method.invoke(holmes, args);
	}
	

	
}

package com.kris.study;

public class Client {
   public static void main(String[] args) {
	   Holmes holmes = new Holmes();
	   FangDongTaiTai giftSendHandler = new FangDongTaiTai();
	   SendGift proxy = giftSendHandler.bindObject(holmes);
	   proxy.send();
   }
}

思考:

代理模式的本質:控制對象的訪問

特點:

遠程代理:Android中的Binder機制就是通過代理實現,本地通過一個代理對象去調用遠程Service的方法。

虛代理:比方載入數據庫中全部人員數據,頁面上僅僅顯示人員名字,點擊名字能夠查看人員詳細信息,這樣先用代理對象載入全部人員的名字和ID.當真正須要看其它詳細信息時,用代理對象再次去數據庫載入全部人員數據。

保護代理:對目標對象的訪問進行權限的管控,在代理對象中須要滿足某種條件才幹調用目標對象的方法。

智能指引:在代理方法的前後運行一些附加的業務邏輯。AOP切面。


何時使用代理:

1.須要為一個對象在不同的地址空間提供局部代表的時候,能夠使用遠程代理

2.須要創建開銷非常大的對象時。能夠使用虛代理。

3.須要控制對原始對象的訪問的時候。能夠使用保護代理

4.須要在訪問對象運行一些附加操作的時候。能夠使用智能指引代理


設計模式學習--------12.代理模式學習