設(shè)計(jì)模式--代理模式(Proxy Pattern)-靜態(tài)代理


間接的“美”
  中國人是一個(gè)含蓄的民族,講究微妙和間接的交流方式。對象間的間接通信也同樣是面向?qū)ο笤O(shè)計(jì)中一條重要的審美觀榄融。間接性的通信可以給出較低的耦合關(guān)系,較強(qiáng)的合作關(guān)系救湖,以及微妙的結(jié)構(gòu)和易于復(fù)用的設(shè)計(jì)架構(gòu)愧杯。
                           ----<<Java與模式>>


1.引言


定義
  代理模式的英文叫Proxy或Surrogate。所謂代理就是指一個(gè)人或者一個(gè)機(jī)構(gòu)代表另一個(gè)人或另一個(gè)機(jī)構(gòu)采取行動(dòng)鞋既。在一些情況下力九,一個(gè)客戶不想或者不能直接引用一個(gè)對象憔维,而代理對象可以在客戶端和目標(biāo)對象之間起到中介作用。
意圖
  為其他對象提供一種代理以控制對這個(gè)對象的訪問畏邢。


2.代理模式的分類

按職責(zé)來劃分,通常有以下使用場景:
1检吆、遠(yuǎn)程代理 :為一個(gè)位于不同地址空間的對象提供一個(gè)局域代表對象舒萎。這個(gè)不同的地址空間可以在本機(jī)上,也可以在另一臺(tái)機(jī)器中蹭沛,遠(yuǎn)程代理又叫“大使”(Ambassaor)臂寝。
2、虛擬代理 :根據(jù)需要?jiǎng)?chuàng)建一個(gè)資源消耗較大的對象摊灭,使得此對象只在需要時(shí)被創(chuàng)建咆贬。
3、Copy-on-Write 代理 :虛擬代理的一種帚呼。把復(fù)制(克绿投小)拖延到只有在客戶端需要時(shí)才啟動(dòng)。
4煤杀、保護(hù)(Protect or Access)代理 :控制對一個(gè)對象的訪問眷蜈,如果有需要,可以給不同用戶提供不同的使用權(quán)限沈自。
5酌儒、Cache代理:為某一個(gè)目標(biāo)的操作結(jié)果提供臨時(shí)的儲(chǔ)存空間,以便多個(gè)客戶端可以共享這個(gè)結(jié)果枯途。
6忌怎、防火墻(Firewall)代理:保護(hù)目標(biāo),不讓惡意用戶接近酪夷。
7榴啸、同步化(Synchronization)代理 :使幾個(gè)用戶在同時(shí)使用一個(gè)對象而沒有沖突。
8晚岭、智能引用(Smart Reference)代理:當(dāng)一個(gè)對象被引用時(shí)插掂,提供一些額外的操作,比如記錄此對象被調(diào)用的次數(shù)腥例。


3.代理模式的結(jié)構(gòu)

代理模式涉及的角色有:

  • 抽象主題角色:聲明了真實(shí)主題和代理主題的共同接口辅甥。這樣一來任何使用真實(shí)主題的地方都可以使用代理主題。
  • 代理主題(Proxy)角色:代理主題角色內(nèi)部含有一個(gè)對真實(shí)主題角色的引用燎竖。從而可以在任何時(shí)候操作真實(shí)主體對象璃弄;代理主題角色提供一個(gè)與真實(shí)主題角色相同的接口,以便在任何時(shí)候都可以代替真實(shí)主題构回;控制對真實(shí)主題的引用夏块,負(fù)責(zé)在需要的時(shí)候創(chuàng)建真實(shí)主題對象(或刪除真實(shí)主題對象)疏咐;代理主題通常在客戶端調(diào)用真實(shí)主題之前或之后都要執(zhí)行某個(gè)操作,而不是單純將調(diào)用傳給真實(shí)主題脐供。
  • 真實(shí)主題角色:定義了代理角色所代表的的真實(shí)對象浑塞。
    實(shí)現(xiàn)的類圖如下圖所示:
    51.png

4.代理模式的時(shí)序

靜態(tài)的類圖不適合反映模式在運(yùn)行時(shí)的特性,時(shí)序圖則更為形象政己,下圖是代理模式的時(shí)序圖表示:
52.png

5.靜態(tài)代理

(1) 靜態(tài)代理
  由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼酌壕,也就是在編譯時(shí)就已經(jīng)將接口,被代理類歇由,代理類等確定下來卵牍。在程序運(yùn)行之前,代理類的.class文件就已經(jīng)生成沦泌。

(2) 靜態(tài)代理簡單實(shí)現(xiàn)
  根據(jù)上面代理模式的類圖糊昙,來寫一個(gè)簡單的靜態(tài)代理的例子。我這兒舉一個(gè)比較粗糙的例子谢谦,假如一個(gè)班的同學(xué)要向老師交班費(fèi)释牺,但是都是通過班長把自己的錢轉(zhuǎn)交給老師。這里回挽,班長就是代理學(xué)生上交班費(fèi)船侧,
班長就是學(xué)生的代理。
  首先厅各,我們創(chuàng)建一個(gè)Person接口镜撩。這個(gè)接口就是學(xué)生(被代理類),和班長(代理類)的公共接口队塘,他們都有上交班費(fèi)的行為袁梗。這樣,學(xué)生上交班費(fèi)就可以讓班長來代理執(zhí)行憔古。
代碼清單一:抽象主題角色的源代碼

// 創(chuàng)建一個(gè)代理類和真實(shí)類的共同接口Person
public interface Person{
    // 上交班費(fèi)
    void giveMoney();
}

代碼清單二:真實(shí)主題源代碼
Student類實(shí)現(xiàn)Person接口遮怜。Student可以具體實(shí)施上交班費(fèi)的動(dòng)作。

public class Student implements Person {
    public Student() {
    }
    @Override
    public void giveMoney() {
       System.out.println("上交班費(fèi)");
    }
}

代碼清單三:代理主題源代碼

/**
 * 學(xué)生代理類鸿市,也實(shí)現(xiàn)了Person接口锯梁,保存一個(gè)學(xué)生實(shí)體,這樣既可以代理學(xué)生產(chǎn)生行為
 */
public class StudentsProxy implements Person{
    //被代理的學(xué)生
    Student stu;
    public StudentsProxy() {
    } 
    //代理上交班費(fèi)焰情,調(diào)用被代理學(xué)生的上交班費(fèi)行為
    public void giveMoney() {
        // 調(diào)用之前進(jìn)行操作
        preGive();
        if(stu == null){
            stu = new Student();
        }
        stu.giveMoney();
        // 調(diào)用之后進(jìn)行操作
        postGive();
    }
    public void preGive(){
         System.out.println("Before:在give Money之前進(jìn)行一些操作");
    }
    public void postGive(){
        System.out.println("After:在give Money之后進(jìn)行一些操作");
    }
}

代碼清單四:測試源代碼

/**
 * Created by yucheng on 2018/8/9.
 */
public class StudentProxyDemo {
    public static void main(String[] args) {
        Person p = new StudentProxy();
        p.giveMoney();
    }
}

輸出結(jié)果
Before Give Money!
上交班費(fèi)陌凳!
After Give Money!


說明
  代理模式最主要的就是有一個(gè)公共接口Person,一個(gè)具體的類Student内舟,一個(gè)代理類StudentProxyDemo,代理類持有具體類的實(shí)例合敦,代為執(zhí)行具體類實(shí)例方法。
  上面說到验游,代理模式就是在訪問實(shí)際對象時(shí)引入一定程度的間接性充岛,因?yàn)檫@種間接性保檐,可以附加多種用途。這里的間接性就是指不直接調(diào)用實(shí)際對象的方法崔梗,那么我們在代理過程中就可以加上一些其他用途夜只。就如這個(gè)例子里的preGive()和postGive()方法。特別是在Spring AOP編程中蒜魄。在切點(diǎn)(即一個(gè)個(gè)方法)的前后我們可以進(jìn)行一系列操作扔亥。


這一章,我們主要講述的是代理模式的基本概念权悟、思想已經(jīng)應(yīng)用之靜態(tài)代理。而下一章推盛,我將繼續(xù)代理模式之“動(dòng)態(tài)代理”的講述峦阁。敬請期待!
推薦閱讀:
設(shè)計(jì)模式--代理模式(Proxy Pattern)-動(dòng)態(tài)代理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耘成,一起剝皮案震驚了整個(gè)濱河市榔昔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘪菌,老刑警劉巖撒会,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異师妙,居然都是意外死亡诵肛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門默穴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怔檩,“玉大人,你說我怎么就攤上這事蓄诽⊙ρ担” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵仑氛,是天一觀的道長乙埃。 經(jīng)常有香客問我,道長锯岖,這世上最難降的妖魔是什么介袜? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮出吹,結(jié)果婚禮上米酬,老公的妹妹穿的比我還像新娘。我一直安慰自己趋箩,他們只是感情好赃额,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布加派。 她就那樣靜靜地躺著,像睡著了一般跳芳。 火紅的嫁衣襯著肌膚如雪芍锦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天飞盆,我揣著相機(jī)與錄音娄琉,去河邊找鬼。 笑死吓歇,一個(gè)胖子當(dāng)著我的面吹牛孽水,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播城看,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼女气,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了测柠?” 一聲冷哼從身側(cè)響起炼鞠,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轰胁,沒想到半個(gè)月后谒主,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赃阀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年霎肯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榛斯。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姿现,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肖抱,到底是詐尸還是另有隱情备典,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布意述,位于F島的核電站提佣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荤崇。R本人自食惡果不足惜拌屏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望术荤。 院中可真熱鬧倚喂,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至舱权,卻和暖如春矗晃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宴倍。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工张症, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸵贬。 一個(gè)月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓俗他,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阔逼。 傳聞我的和親對象是個(gè)殘疾皇子兆衅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

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