通過使用Gmail,進一步理解軟件設計模式中的代理模式(Proxy pattern).
?
Gmail郵箱的使用需求:
一直使用的郵箱A,所有的郵件進出的直接使用郵箱;
大量的團隊郵箱C1,C2,C3,...,Cn;
以前被廢棄的郵箱D1,D2,D3,...,Dm。
為了使用的方便,我們希望所有的團隊郵箱中的郵件能夠自動轉發到A,被廢棄的郵箱能夠自動轉發郵件到A。一般情況下,我們可以簡單的通過讓C系、D系郵箱自動轉發到A,不支持轉發的可以通過Gmail自帶的郵件提取功能去主動提取郵件。
我們似乎看到了解決的方法,但是對于有“潔癖”的朋友可能發現這樣的問題:
郵件e同時發送到A,C1,D1,則出現了A中出現了三封一樣的郵件e,這樣不論是視覺上還是空間上面都是一種浪費。能否將其過濾掉呢?在這個時候大家可能容易想到那些強大的郵件過濾器機制。但是經過嘗試,你會發現隨著n、m值的增多,我們可能需要在A中設置大量的復雜的過濾機制,這樣我們就增加了日常郵件系統的維護。這讓我們很容易想到請別的人幫我們做過濾,在公司中你可能會有機會被配一個秘書來做此事,但是更多的人可能就得自我來“人肉法”了。那么我們能否請一個自動秘書呢?通過這個思路,我們在直接給A轉發各種郵件時,先通過一個秘書,讓秘書做統一的過濾后做再次轉發至A.
以上就是通過一個統一的過濾秘書B,來達到簡潔處理的效果。以后再有C系、D系郵箱的增加,我們就直接讓他們轉發到秘書B那里就好了。
如此以來,我們簡化了A的過濾規則,提高了以后擴展郵箱時的速度。 在這里我只是拋磚引玉,其實B中的過濾轉發條件是豐富多樣了,大家可以根據自己的具體需要來定制。
現在我們將解決方案引申,可以得到一種稱為“代理”的廣義社會生活的解決方案。
?
什么是代理?
代理基本上為財產法上概念,具一身專屬性質的身分行為原則上不許代理;另外,侵權行為也不能代理。
1.委托代理,是基于被代理人的委托而發生的代理關系;
2.法定代理,是根據法律的直接規定而發生的代理關系;
3.指定代理,是根據人民法院和有關單位的指定而發生的代理關系。
代理人在代理權限內,以被代理人的名義進行民事活動,其法律后果直接由被代理人承受的法律制度。代理是三方人之間的民事法律關系,即代理人與被代理人之間的關系,代理人與第三人之間的關系,第三人與被代理人之間的關系。
代理的適用范圍包括:
1.代理實施法律行為,如代理進行買賣、租賃、簽訂合同和履行債務等;
2.代理進行民事訴訟;
3.代理履行某些財政、行政義務,如代理進行房屋登記、法人登記、商標注冊。納稅等。但某些具有人身性質的民事行為如婚姻登記、收養子女、立遺囑等,以及某些具有人身性質的債務如約稿合同、演出合同等,依法須由本人親自履行的,不能代理。此外,侵權行為和內容違法的行為,也不能進行代理。
?在我理解,代理就是代替我們處理一些事務。
?
現在我們來看看設計模式中的經典設計模式之一“代理模式”。
我第一次看到代理模式,是在《Head First 設計模式》中看到的,里面的引入例子就是我們在Java中通常使用的RMI.其實我感覺這個例子不夠生動,至少我使用這個東西的機會很少;后來我又在使用Spring時看到了大量使用代理模式的樣例和具體使用場景,這里面的例子則及其生動的展現了一個代理的所作所為(從XML綁定,到后面的使用都體現了這個優秀的設計模式的優越性)。
......................................................
二、定義和分類
代理模式在設計模式中的定義就是:為其他對象提供一種代理以控制對這個對象的訪問。說白了就是,在一些情況下客戶不想或者不能直接引用一個對象,而代理對象可以在客戶和目標對象之間起到中介作用,去掉客戶不能看到的內容和服務或者增添客戶需要的額外服務。
那么什么時候要使用代理模式呢?在對已有的方法進行使用的時候出現需要對原有方法進行改進或者修改,這時候有兩種改進選擇:修改原有方法來適應現在的使用方式,或者使用一個“第三者”方法來調用原有的方法并且對方法產生的結果進行一定的控制。第一種方法是明顯違背了“對擴展開放、對修改關閉”(開閉原則),而且在原來方法中作修改可能使得原來類的功能變得模糊和多元化(就像現在企業多元化一樣),而使用第二種方式可以將功能劃分的更加清晰,有助于后面的維護。所以在一定程度上第二種方式是一個比較好的選擇!
當然,話又說回來了,如果是一個很小的系統,功能也不是很繁雜,那么使用代理模式可能就顯得臃腫,不如第一種方式來的快捷。這就像一個三口之家,家務活全由家庭主婦或者一個保姆來完成是比較合理的,根本不需要雇上好幾個保姆層層代理:)
根據《Java與模式》書中對代理模式的分類,代理模式分為8種,這里將幾種常見的、重要的列舉如下:
1. 遠程(Remote)代理:為一個位于不同的地址空間的對象提供一個局域代表對象。比如:你可以將一個在世界某個角落一臺機器通過代理假象成你局域網中的一部分。
2. 虛擬(Virtual)代理:根據需要將一個資源消耗很大或者比較復雜的對象延遲的真正需要時才創建。比如:如果一個很大的圖片,需要花費很長時間才能顯示出來,那么當這個圖片包含在文檔中時,使用編輯器或瀏覽器打開這個文檔,這個大圖片可能就影響了文檔的閱讀,這時需要做個圖片Proxy來代替真正的圖片。
3. 保護(Protect or Access)代理:控制對一個對象的訪問權限。比如:在論壇中,不同的身份登陸,擁有的權限是不同的,使用代理模式可以控制權限(當然,使用別的方式也可以實現)。
4. 智能引用(Smart Reference)代理:提供比對目標對象額外的服務。比如:紀錄訪問的流量(這是個再簡單不過的例子),提供一些友情提示等等。
代理模式是一種比較有用的模式,從幾個類的“小結構”到龐大系統的“大結構”都可以看到它的影子。
三、結構
代理模式中的“代理商”要想實現代理任務,就必須和被代理的“廠商”使用共同的接口(你可以想象為產品)。所以自然而然你會想到在java中使用一個抽象類或者接口(推薦)來實現這個共同的接口。于是代理模式就有三個角色組成了:
1.抽象主題角色:聲明了真實主題和代理主題的共同接口。
2.代理主題角色:內部包含對真實主題的引用,并且提供和真實主題角色相同的接口。
3.真實主題角色:定義真實的對象。
使用類圖來表示下三者間的關系如下:

?
當然,圖上所示的是代理模式中的一個具體情況。而代理模式可以非常靈活的使用其他方式來實現,這樣就與圖上所示有很大的區別。
也許,現在你已經對代理模式已經有了一個宏觀的認識了,下面我們來看看怎么實際的使用代理模
式
.........................
?網上有很多討論這個設計模式的文章,我的開發經驗有限在這里就不獻丑了。
?
總結:
- 設計模式不僅僅可以使用在軟件設計中,更可以發揮我們的想像將它們使用到一切適用的地方。本身這一個個模式都來源于生活嘛。
- 充分利用網上的各個工具,力爭使我們的工作生活娛樂“低耦合”、“高內聚”、“易擴展”。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
