代理模式
代理模式屬于結(jié)構(gòu)型模式.分為靜態(tài)代理與動(dòng)態(tài)代理.
比如說(shuō) 用戶(hù)現(xiàn)在要買(mǎi)車(chē),只要一輛車(chē)直接去車(chē)商買(mǎi),肯定不會(huì)賣(mài)給你啊.這個(gè)時(shí)候用戶(hù)就會(huì)找到4S店
讓4S店幫忙購(gòu)買(mǎi),在從4S那兒買(mǎi)到車(chē)子.
在整個(gè)交易過(guò)程中4S的存在就是一個(gè)代理商,用戶(hù)作為委托者,代理商幫委托者完成委托者的述求.
應(yīng)用場(chǎng)景
- 為一個(gè)對(duì)象的引用提供額外操作
- 控制一個(gè)對(duì)象的訪問(wèn),為不同的用戶(hù)提供不同的權(quán)限級(jí)別
- 被訪問(wèn)對(duì)象不想暴露所有細(xì)節(jié)方法,可代理不想暴露的方法
- 一個(gè)對(duì)象不想直接被另一個(gè)對(duì)象訪問(wèn)
代碼示例(靜態(tài)代理)
(一)抽象購(gòu)車(chē)代理接口
public interface Car {
void buyCar();
}
(二)用戶(hù)實(shí)現(xiàn)購(gòu)車(chē)接口
public class UserBuyCar implements Car {
private String name;
@Override
public void buyCar() {
System.out.print("\n"+"用戶(hù)買(mǎi)了"+getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(三)代理商4S店
public class CarStoreProxy implements Car {
private UserBuyCar car;
public CarStoreProxy(UserBuyCar car) {
this.car = car;
}
@Override
public void buyCar() {
if (car.getName().equals(ProxyTest.AUDI) ||
car.getName().equals(ProxyTest.BMW) ||
car.getName().equals(ProxyTest.BENZ)) {
car.buyCar();
} else {
System.out.print("\n" + "用戶(hù)什么也沒(méi)買(mǎi)");
}
}
}
(四)調(diào)用方式
//靜態(tài)代理 買(mǎi)奧迪
UserBuyCar userBuyCar=new UserBuyCar();
userBuyCar.setName(AUDI);
CarStoreProxy audiCarStoreProxy=new CarStoreProxy(userBuyCar);
audiCarStoreProxy.buyCar();
//靜態(tài)代理 什么也不買(mǎi)
UserBuyCar userBuyCar1=new UserBuyCar();
userBuyCar1.setName(NONE);
CarStoreProxy carStoreProxy=new CarStoreProxy(userBuyCar1);
carStoreProxy.buyCar();
顯示結(jié)果
用戶(hù)買(mǎi)了audi
用戶(hù)什么也沒(méi)買(mǎi)
以上為用戶(hù)買(mǎi)車(chē)過(guò)程中,4S作為代理商,用戶(hù)委托買(mǎi)車(chē)的流程案例.實(shí)現(xiàn)類(lèi)和代理類(lèi)保證統(tǒng)一性必須都實(shí)現(xiàn)同一個(gè)接口方法.含有具體的代理類(lèi).
接口也只能作用于當(dāng)前這個(gè)用戶(hù),如果新添加了方法(租車(chē)),所有的實(shí)現(xiàn)類(lèi)和代理類(lèi)都需要實(shí)現(xiàn)新方法.
-
靜態(tài)代理優(yōu)點(diǎn)
- 使用者只需要關(guān)注用戶(hù)業(yè)務(wù)自身的邏輯
-
靜態(tài)代理缺點(diǎn)
- 一個(gè)接口只能作用于一個(gè)對(duì)象
- 接口新方法后,所有實(shí)現(xiàn)類(lèi) 代理類(lèi)都需要新增方法
代碼示例(動(dòng)態(tài)代理)
在代理模式中的動(dòng)態(tài)代理,不同于靜態(tài)代理含有具體代理類(lèi).
動(dòng)態(tài)代理中只要通過(guò)反射機(jī)制動(dòng)態(tài)生成代理類(lèi),具體代理對(duì)象在運(yùn)行時(shí)生成.
Java動(dòng)態(tài)代理Proxy
/獲取指定代理對(duì)象所關(guān)聯(lián)的調(diào)用處理器
static InvocationHandler getInvocationHandler(Object proxy )
獲取關(guān)聯(lián)于指定類(lèi)裝載器和一組接口的動(dòng)態(tài)代理類(lèi)的類(lèi)對(duì)象
static Class getProxyClass(ClassLoader loader,Class[] interfaces)
判斷指定類(lèi)對(duì)象是否是一個(gè)動(dòng)態(tài)代理類(lèi)
static boolean isProxyClass(Class cl )
為指定類(lèi)裝載器、一組接口及調(diào)用處理器生成動(dòng)態(tài)代理類(lèi)實(shí)例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h )
在newProxyInstance第三個(gè)參數(shù)中的InvocationHandler含有一個(gè)invoke方法,實(shí)現(xiàn)對(duì)委托者代理訪問(wèn),在每次動(dòng)態(tài)代理都需要通過(guò)它指定的調(diào)用器對(duì)象.
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object,args);
return result;
}
實(shí)現(xiàn)InvocationHandler定義動(dòng)態(tài)代理類(lèi)
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(object,args);
return result;
}
}
調(diào)用方式
//動(dòng)態(tài)代理 買(mǎi)奔馳
UserBuyCar userBuyCar2=new UserBuyCar();
userBuyCar2.setName(BENZ);
DynamicProxy dynamicProxy=new DynamicProxy(userBuyCar2);
Car car=(Car) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Car.class}, dynamicProxy);
car.buyCar();
顯示結(jié)果
用戶(hù)買(mǎi)了benz
結(jié)果與靜態(tài)代理效果一致,調(diào)用只需要傳入具體的委托者即可動(dòng)態(tài)生成代理類(lèi).相比于靜態(tài)代理更為靈活方便