設(shè)計模式(六)代理模式

1.代理模式簡介

代理模式介紹

代理模式也叫委托模式译秦,是結(jié)構(gòu)型設(shè)計模式的一種。在現(xiàn)實生活中我們用到類似代理模式的場景有很多劣纲,比如代購逢捺、代理上網(wǎng)、打官司等癞季。

定義

為其他對象提供一種代理以控制這個對象的訪問劫瞳。

代理模式結(jié)構(gòu)圖

  • Subject:抽象主題類,聲明真實主題與代理的共同接口方法绷柒。
  • RealSubject:真實主題類志于,定義了代理所表示的真實對象,客戶端通過代理類間接的調(diào)用真實主題類的方法废睦。
  • ProxySubject:代理類伺绽,持有對真實主題類的引用,在其所實現(xiàn)的接口方法中調(diào)用真實主題類中相應(yīng)的接口方法執(zhí)行。
  • Client:客戶端類奈应,由它來調(diào)用代理類澜掩。

2.代理模式的簡單實現(xiàn)

假設(shè)我要買一個BV的包(博主我很喜歡一直買不起),國內(nèi)的太貴了杖挣,我找了個代購來幫我海外購買肩榕,這樣能省好多錢,哈哈程梦。

抽象主題類(Subject)

抽象主題類具有真實主題類和代理的共同接口方法点把,我想要代購,那共同的方法就是購買:

public interface IShop {
    //購買
    void buy();
}

真實主題類(RealSubject)

這個購買者LiuWangShu也就是我屿附,實現(xiàn)了IShop接口提供的 buy()方法:

public class LiuWangShu implements IShop {
    @Override
    public void buy() {
        System.out.println("購買");
    }
}

代理類(ProxySubject)

我找的代理類同樣也要實現(xiàn)IShop接口郎逃,并且要持有被代理者,在buy()方法中調(diào)用了被代理者的buy()方法:

public class Purchasing implements IShop {
    private IShop mShop;
    public Purchasing(IShop shop){
        mShop=shop;
    }

    @Override
    public void buy() {
        mShop.buy();
    }
}

客戶端類(Client)

public class Client {
    public static void main(String[] args){
        //創(chuàng)建LiuWangShu
        IShop liuwangshu=new LiuWangShu();
        //創(chuàng)建代購者并將LiuWangShu作為構(gòu)造函數(shù)傳
        IShop purchasing=new Purchasing(liuwangshu);
        purchasing.buy();
    }
}

看完客戶端類的代碼挺份,其實也是很好理解褒翰,就是代理類包含了真實主題類(被代理者),最終調(diào)用的都是真實主題類(被代理者)實現(xiàn)的方法匀泊,在上面的例子就是LiuWangShu類的buy()方法优训,所以運行的結(jié)果就是“購買”。

3.動態(tài)代理的簡單實現(xiàn)

從編碼的角度來說各聘,代理模式分為靜態(tài)代理和動態(tài)代理揣非,上面的例子是靜態(tài)代理,在代碼運行前就已經(jīng)存在了代理類的class編譯文件躲因,而動態(tài)代理則是在代碼運行時通過反射來動態(tài)的生成代理類的對象早敬,并確定到底來代理誰。也就是我們在編碼階段不需要知道代理誰大脉,代理誰我們將會在代碼運行時決定搞监。Java提供了動態(tài)的代理接口InvocationHandler,實現(xiàn)該接口需要重寫invoke()方法镰矿。下面我們在上面靜態(tài)代理的例子上做修改:

創(chuàng)建動態(tài)代理類:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicPurchasing implements InvocationHandler{
    private Object obj;
    public DynamicPurchasing(Object obj){
        this.obj=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result=method.invoke(obj, args);
        return result;
    }
}

在動態(tài)代理類中我們聲明一個Object的引用琐驴,該引用指向被代理類,我們調(diào)用被代理類的具體方法在invoke()方法中執(zhí)行秤标。接下來我們修改客戶端類代碼:

import java.lang.reflect.Proxy;
public class Client {
    public static void main(String[] args){
        //創(chuàng)建LiuWangShu
        IShop liuwangshu=new LiuWangShu();
        //創(chuàng)建動態(tài)代理
        DynamicPurchasing  mDynamicPurchasing=new DynamicPurchasing(liuwangshu);
        //創(chuàng)建LiuWangShu的ClassLoader
        ClassLoader loader=liuwangshu.getClass().getClassLoader();
        //動態(tài)創(chuàng)建代理類
        IShop purchasing= (IShop) Proxy.newProxyInstance(loader,new Class[]{IShop.class},mDynamicPurchasing);
        purchasing.buy();
    }
}

4.代理模式的應(yīng)用

代理模式類型

代理模式的類型主要有以下幾點:

  1. 遠程代理:為一個對象在不同的地址空間提供局部代表绝淡,這樣系統(tǒng)可以將Server部分的事項隱藏。
  2. 虛擬代理:使用一個代理對象表示一個十分耗資源的對象并在真正需要時才創(chuàng)建苍姜。
  3. 安全代理:用來控制真實對象訪問時的權(quán)限够委。
  4. 智能指引:當(dāng)調(diào)用真實的對象時,代理處理另外一些事怖现,比如計算真實對象的引用計數(shù)茁帽,當(dāng)該對象沒有引用時玉罐,可以自動釋放它;或者訪問一個實際對象時潘拨,檢查是否已經(jīng)能夠鎖定它吊输,以確保其他對象不能改變它。

代理模式使用場景

無法或者不想直接訪問某個對象時可以通過一個代理對象來間接的訪問铁追。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末季蚂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子琅束,更是在濱河造成了極大的恐慌扭屁,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涩禀,死亡現(xiàn)場離奇詭異料滥,居然都是意外死亡,警方通過查閱死者的電腦和手機艾船,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門葵腹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屿岂,你說我怎么就攤上這事践宴。” “怎么了爷怀?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵阻肩,是天一觀的道長。 經(jīng)常有香客問我运授,道長磺浙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任徒坡,我火速辦了婚禮,結(jié)果婚禮上瘤缩,老公的妹妹穿的比我還像新娘喇完。我一直安慰自己,他們只是感情好剥啤,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布锦溪。 她就那樣靜靜地躺著,像睡著了一般府怯。 火紅的嫁衣襯著肌膚如雪刻诊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天牺丙,我揣著相機與錄音则涯,去河邊找鬼复局。 笑死,一個胖子當(dāng)著我的面吹牛粟判,可吹牛的內(nèi)容都是我干的亿昏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼档礁,長吁一口氣:“原來是場噩夢啊……” “哼角钩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呻澜,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤递礼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后羹幸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脊髓,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年睹欲,在試婚紗的時候發(fā)現(xiàn)自己被綠了供炼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡窘疮,死狀恐怖袋哼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闸衫,我是刑警寧澤涛贯,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站蔚出,受9級特大地震影響弟翘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骄酗,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一稀余、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧趋翻,春花似錦睛琳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至讨惩,卻和暖如春辟癌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荐捻。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工黍少, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留寡夹,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓仍侥,卻偏偏與公主長得像要出,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子农渊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計模式匯總 一患蹂、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,944評論 1 15
  • 整體Retrofit內(nèi)容如下: 1砸紊、Retrofit解析1之前哨站——理解RESTful 2传于、Retrofit解析...
    隔壁老李頭閱讀 3,236評論 2 10
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)醉顽,斷路器沼溜,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法游添,內(nèi)部類的語法系草,繼承相關(guān)的語法,異常的語法唆涝,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 蘋果爸爸: 1改掉自己懶散的習(xí)慣 2做一個樂于傾聽的人 3用行動讓身邊的人看到我的變化 4不和家人發(fā)脾氣 5讓孩子...
    d090d5f5944d閱讀 118評論 0 0