前言
代理模式是一種結(jié)構(gòu)型設(shè)計模式,主要用來解決直接訪問對象帶來的問題。目地是為其他對象提供一個代理以控制某個對象的訪問。代理分為靜態(tài)代理和動態(tài)代理,先說靜態(tài)代理,概念總是太抽象,直接用代碼說明吧。
靜態(tài)代理類圖如下:

結(jié)構(gòu)型設(shè)計模式代理模式:靜態(tài)代理類圖.jpg
抽象主題 聲明一個接口
// 抽象主題 是一個接口,以一個工廠接口為例
public interface IToolFactory(){
public void makeProduct();
}
定義一個真實(shí)的主題,用來實(shí)實(shí)在在做事的,以工廠為例,用來加工產(chǎn)品
public class ARealFactory implement IToolFactory(){
@Override
public void makeProduct(){
System.out.println("我加工生產(chǎn)出來了你們所需要的產(chǎn)品。");
}
}
下面是一個最重要的角色,代理類Proxy 相當(dāng)于代購者
public class Proxy implements IToolFactory(){
ARealFactory factory;
public Proxy(ARealFactory factory){
this.factory = factory;
}
public void doBefore(){
System.out.println("售前咨詢,可以提出客戶的需求");
}
public void doAfter(){
System.out.println("售后服務(wù),解決客戶的后顧之憂");
}
@Override
public void makeProduct(){
if(factory == null){
factory = new ARealFactory();
}
doBefore();
factory.makeProduct();
doAfter();
}
}
我們的顧客需要購買產(chǎn)品,就需要找代購
public class Customer(){
public static void main(String args[]){
//實(shí)例化一個真實(shí)的工廠
// IToolFactory factory = new ARealFactory();
//代購者需要持有真實(shí)對象
Proxy proxy = new Proxy();
proxy.makeProduct();
}
}
小結(jié):
以上就是靜態(tài)代理的設(shè)計模式的原理演示。靜態(tài)代理的缺點(diǎn)就是違反了開閉原則,擴(kuò)展能力差,可維護(hù)性差。因此就有了動態(tài)代理設(shè)計模式。
動態(tài)代理
在靜態(tài)代理的基礎(chǔ)上,我們進(jìn)行改進(jìn):主要修改代理類Proxy, 通過反射獲取動態(tài)代理對象。
public class MarkCompany implements InvokeHandler{
private Object factory;
public void setFactory(Object factory){
this.factory = factory;
}
public Object getFactory(){
return this.factory;
}
// 關(guān)鍵方法:獲取動態(tài)代理對象
public Object getProxyInstance(){
return Proxy.newProxyInstance(factory.getclass().getClassLoader(),facory.getClass().getInterfaces(),this);
}
/**
* 通過動態(tài)代理對象進(jìn)行增強(qiáng)
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy,Method method,Object[] args){
doBefore();
method.invoke(factory,args);
doAfter();
return null;
}
public void doBefore(){
System.out.println("售前咨詢,可以提出客戶的需求");
}
public void doAfter(){
System.out.println("售后服務(wù),解決客戶的后顧之憂");
}
}
調(diào)用有點(diǎn)小小的區(qū)別:
IToolFactory realFactory = new ARealFactory();
MarkCompany company = new MarkCompany();
company.setFactory(realFactory);
IToolFactory employ1 = (IToolCompany)company.getProxyInstance();
employ1.makeProduct();
結(jié)語
在實(shí)際開發(fā)過程中,由于靜態(tài)代理的局限性,用到的地方較少,可以會用于代理對象較少,比較固定不需要擴(kuò)展的場景。
雖然,動態(tài)代理運(yùn)用到了反射,性能會不及靜態(tài)代理,但是由于動態(tài)代理的各種好處優(yōu)點(diǎn),非常強(qiáng)大,犧牲點(diǎn)性能還是值得的。