1胁艰、什么是代理模式
- 是指為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。在某些情況下腋么,一個(gè)對(duì)象不適合或者不能直接引用另一個(gè)對(duì)象刻坊,而代理對(duì)象可以在客戶(hù)端和目標(biāo)之間起到中介的作用。
- 代理模式屬于結(jié)構(gòu)型模式党晋。
- 代理模式的組成主要有
- 抽象角色:通過(guò)接口或者抽象類(lèi)聲明真實(shí)角色實(shí)現(xiàn)的業(yè)務(wù)方法谭胚。
- 代理角色:實(shí)現(xiàn)抽象角色,是真實(shí)角色的代理未玻,通過(guò)真實(shí)角色的業(yè)務(wù)邏輯方法來(lái)實(shí)現(xiàn)抽象方法灾而,并可以附加自己的操作。
- 真實(shí)角色:實(shí)現(xiàn)抽象角色扳剿,定義真實(shí)角色所要實(shí)現(xiàn)的業(yè)務(wù)邏輯旁趟,供代理角色調(diào)用。
- 代理模式的主要類(lèi)型有:靜態(tài)代理庇绽,動(dòng)態(tài)代理
2锡搜、靜態(tài)代理
靜態(tài)代理是由程序員創(chuàng)建或工具生成代理類(lèi)的源碼,再編譯代理類(lèi)瞧掺。
舉個(gè)例子耕餐,我有輛車(chē),要去外省辟狈,車(chē)就是真實(shí)角色肠缔,但是我不會(huì)開(kāi)車(chē),需要請(qǐng)個(gè)司機(jī)哼转,司機(jī)就是代理角色明未。兩者都實(shí)現(xiàn)一個(gè)共同的抽象類(lèi),交通類(lèi)壹蔓。
抽象角色
public interface Vehicle{
void run();
}
真實(shí)角色
public class Car implements Vehicle{
public void run(){
System.out.println("小汽車(chē)出省趟妥。。佣蓉。");
}
}
代理角色
public class Driver implements Vehicle{
private Car car ;
public Driver(Car car){
this.car = car;
}
public void run(){
System.out.println("我是司機(jī)披摄,代理開(kāi)車(chē)亲雪。。行疏。");
if(car == null ){
car = new Car();
}
this.car.run();
}
}
測(cè)試類(lèi)
public class GoTest{
public static void main (String[] args){
Vehicle go = new Driver(new Car());
go.run();
}
}
輸出結(jié)果是
以上這種模式是靜態(tài)代理模式匆光,通過(guò)司機(jī)這個(gè)代理訪問(wèn)小汽車(chē)套像,還可以加上司機(jī)自己的一些操作酿联。
3、動(dòng)態(tài)代理
動(dòng)態(tài)代理是指在運(yùn)行時(shí)夺巩,動(dòng)態(tài)生成代理類(lèi)贞让。動(dòng)態(tài)代理的方式可以分jdk動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理等。
- jdk動(dòng)態(tài)代理
jdk代理是指用java的jdk中的代理類(lèi)中的api創(chuàng)建代理類(lèi)柳譬。在jdk代理中喳张,代理角色可以不用實(shí)現(xiàn)接口。
jdk實(shí)現(xiàn)代理只需要使用java.lang.reflect.Proxy中的newProxyInstance方法美澳,該方法是靜態(tài)方法销部。static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
方法中存在三個(gè)參數(shù),第一個(gè)是目標(biāo)對(duì)象使用類(lèi)加載器制跟,第二個(gè)是目標(biāo)對(duì)象實(shí)現(xiàn)的接口類(lèi)型舅桩,第三個(gè)是事件處理,執(zhí)行目標(biāo)對(duì)象方法時(shí)會(huì)觸發(fā)事件處理器雨膨。
抽象角色和真實(shí)角色同上擂涛。
這里創(chuàng)建一個(gè)代理類(lèi)工廠。
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
//給目標(biāo)對(duì)象生成代理對(duì)象
public Object getDriver(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是司機(jī)聊记。撒妈。。排监。");
Object returnValue = method.invoke(target,args);
return returnValue;
}
}
);
}
}
測(cè)試方法
public class GoTest{
public static void main (String[] args) {
Car car = new Car();
Vehicle driver = (Vehicle)new ProxyFactory(car).getDriver();
driver.run();
}
}
測(cè)試結(jié)果
動(dòng)態(tài)代理同樣可以完成和靜態(tài)代理一樣的效果狰右,而且可以不用事先寫(xiě)好程序編譯,靈活性更強(qiáng)舆床。
4挟阻、總結(jié)
- 代理模式的優(yōu)點(diǎn): 1、職責(zé)清晰峭弟。 2附鸽、高擴(kuò)展性。 3瞒瘸、智能化坷备。
- 代理模式的缺點(diǎn):1、由于在客戶(hù)端和真實(shí)主題之間增加了代理對(duì)象情臭,因此有些類(lèi)型的代理模式可能會(huì)造成請(qǐng)求的處理速度變慢省撑。 2赌蔑、實(shí)現(xiàn)代理模式需要額外的工作,有些代理模式的實(shí)現(xiàn)非常復(fù)雜竟秫。
- 代理模式需要注意的一些地方: 1娃惯、和適配器模式的區(qū)別:適配器模式主要改變所考慮對(duì)象的接口,而代理模式不能改變所代理類(lèi)的接口肥败。 2趾浅、和裝飾器模式的區(qū)別:裝飾器模式為了增強(qiáng)功能,而代理模式是為了加以控制馒稍。
參考
http://blog.csdn.net/u013256816/article/details/51009592
https://baike.baidu.com/item/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/8374046?fr=aladdin
https://www.cnblogs.com/cenyu/p/6289209.html
http://blog.csdn.net/goskalrie/article/details/52458773
https://www.cnblogs.com/lixiuyu/p/5919643.html
http://www.runoob.com/design-pattern/proxy-pattern.html