結(jié)構(gòu)型設(shè)計模式 之 代理模式 (靜態(tài)代理和動態(tài)代理)

前言

代理模式是一種結(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)性能還是值得的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 執(zhí)傘閑漫寂寥雨巷,細(xì)露沾羅裙,梧桐繞指,裊裊無絆,盈盈扇掩珊瑚唇。 氤氳霽雨,紅妝凝眸而淺笑嫣然。煙雨江南執(zhí)傘,入...
    9月滿圓閱讀 1,667評論 0 2
  • 當(dāng)我重新翻起床頭的那一本《朝花夕拾》,那澀黃色的紙張,伴隨著字墨的香味,依然圍繞在我的身旁。已經(jīng)不知道...
    43吳天宇閱讀 544評論 0 0
  • 學(xué)習(xí)有兩種:一種是學(xué)習(xí)前人總結(jié)到書藉上面的知識,另一種是通過實(shí)踐,學(xué)習(xí)怎樣去發(fā)掘我們所不知曉的。早上好
    帥氣的頭腦閱讀 320評論 0 0
  • 作業(yè): 1.寫一兩段話(如回憶一個場景),其中包含有觸覺和身體感覺。 早高峰的地鐵站,猶如古戰(zhàn)場,每個人臉上都是視...
    久邇閱讀 624評論 2 0

友情鏈接更多精彩內(nèi)容