代理(Proxy)顧名思義:為避免2者之間直接接觸,委托方尋求第三方(代理方)幫忙處理一些委托方的需求。最經(jīng)典的例子就是打官司:委托方就是被代理方,律師就是代理方,律師的職責(zé)就是避免原被告直接接觸。
一、使用場景
如果2者之間需要通信,且2者之間必須解耦,需引入一個三方類來預(yù)處理通信、和通信結(jié)果處理。這個三方類就是代理類。
代理類能完全控制對委托對象的直接訪問,也可以保護委托對象不被直接訪問,同時也預(yù)留了通信處理空間,在設(shè)計上有更大的靈活性。
二、靜態(tài)代理方式
1、被代理者
/**
* 作者: Created by AdminFun
* 郵箱: 614484070@qq.com
* 創(chuàng)建: 2019/1/4
* 修改: 2019/1/4
* 版本: v1.0.0
* 描述: 被代理者
*/
public class CS35Info implements ICar {
@Override
public double getPrice() {
return 90000;
}
@Override
public String getModel() {
return "長安CS35";
}
}
2、靜態(tài)代理
/**
* 作者: Created by AdminFun
* 郵箱: 614484070@qq.com
* 創(chuàng)建: 2019/1/4
* 修改: 2019/1/4
* 版本: v1.0.0
* 描述: 靜態(tài)代理
* <p>
* 靜態(tài)代理的寫法和裝飾器有點類似,區(qū)別在于:
* 1、代理的構(gòu)造傳入的是實例,而裝飾器構(gòu)造傳入的是抽象
* 2、代理想要控制實例的訪問權(quán)限,而裝飾意在控制對象的行為
*/
public class ProxyStatic implements ICar {
private CS35Info cs35Info;
public ProxyStatic(CS35Info cs35Info) {
this.cs35Info = cs35Info;
}
@Override
public double getPrice() {
return cs35Info.getPrice();
}
@Override
public String getModel() {
return cs35Info.getModel();
}
}
3、調(diào)用
/**
* 作者: Created by AdminFun
* 郵箱: 614484070@qq.com
* 創(chuàng)建: 2019/1/4
* 修改: 2019/1/4
* 版本: v1.0.0
*/
public class ProxyTest {
public static void main() {
// 靜態(tài)代理
ProxyStatic proxyStatic = new ProxyStatic(new CS35Info());
Log.d("common", "靜態(tài)代理:" + proxyStatic.getModel());
}
}
三、動態(tài)代理
被代理方還是上面的被代理類,這里不再重寫。
1、動態(tài)代理
/**
* 作者: Created by AdminFun
* 郵箱: 614484070@qq.com
* 創(chuàng)建: 2019/1/4
* 修改: 2019/1/4
* 版本: v1.0.0
* 描述:動態(tài)代理
* 動態(tài)代理和靜態(tài)代理的區(qū)別
* 1、靜態(tài)代理需要代理方和委托方都實現(xiàn)相同的接口,接口方法變動后,雙方都要隨著變動,代碼維護成本增加。
* 2、動態(tài)代理是利用反射機制,可代理任何對象,且不需要維護成本。
*/
public class ProxyDynamic implements InvocationHandler {
private Object target;//被代理的對象
public ProxyDynamic(Object obj) {
this.target = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}
2、調(diào)用
/**
* 作者: Created by AdminFun
* 郵箱: 614484070@qq.com
* 創(chuàng)建: 2019/1/4
* 修改: 2019/1/4
* 版本: v1.0.0
*/
public class ProxyTest {
public static void main() {
// 動態(tài)代理
final ICar car = new CS35Info();
// 方式1
ICar proxy = (ICar) Proxy.newProxyInstance(
car.getClass().getClassLoader(),
car.getClass().getInterfaces(),
new ProxyDynamic(car)
);
// 方式2
ICar proxy1 = (ICar) Proxy.newProxyInstance(
car.getClass().getClassLoader(),
car.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(car, args);
}
});
Log.d("common", "動態(tài)代理:" + proxy1.getModel());
}
}