好吧,這次的設計模式,我從最愛的足球談起。
嗯,球員不是演員,想要行賄球員好比門將放球進去,這樣演起來真的挺難,但作為裁判,對於一些爭議性的問題,往往可以通過一些手段讓他“看清”到底是哪方球員犯規在先,於是,球隊老闆們就決定跟裁判套套近乎了,可這必經是違法的事情,怎麼辦呢,一級官壓死人,於是他們想到了足協,於是,球隊老闆-足協領導-裁判,就成了這proxy pattern的產業鏈,用戶端-代理-服務端。
來看一下代碼吧:
using System;using System.Collections.Generic;using System.Text;namespace ConsoleApplication1{ abstract class Intention { abstract public void ControlGame(); } class FTManager { public FTManager() { Console.WriteLine("shen yang hai shi lao ban:i can't ask the judge to do anything,so i turn to Football Association to get some help"); } public void BeginTheMatch() { FTAssociationProxy someBody = new FTAssociationProxy(); someBody.ControlGame(); } } class Judge:Intention { public override void ControlGame() { Console.WriteLine("huang jun jie:ok,let's begin,i can control this game 'fairly'"); } } class FTAssociationProxy { private Judge aJudge; public void ControlGame() { Console.WriteLine("nan yong:i'm the Football Association,i can order every judge"); if (aJudge == null) aJudge = new Judge(); aJudge.ControlGame(); } } class Program { static void Main(string[] args) { FTManager aManager = new FTManager(); aManager.BeginTheMatch(); } }}
作為代理,某些足協領導去尋求裁判協助完成操縱比賽的任務要比球隊老闆直接聯絡裁判更方便,因為,領導和裁判,已經合作好久了。
好吧,來看一下這個入門理解很簡單的proxy pattern:
定義
代理模式(Proxy)為另一個對象提供一個替身或預留位置以控制對這個對象的訪問,簡而言之就是用一個對象來代表另一個對象。
代理模式非常常用,大致的思想就是通過為對象加一個代理來降低對象的使用複雜度、或是提升對象使用的友好度、或是提高對象使用的效率。
在我看來代理就好比是簡單的封裝,把一系列的問題通過統一的介面進行了規劃,而我們通過這個代理,就可以有條理的實現一些複雜到我們不能實現的功能。
意圖
提供其他對象一個代理或預留位置,來控制該對象的存取權限。
緣由:
為什麼我們要控制對象的存取權限呢?其中一個原因是通過控制來延遲物件的建立和執行個體化,直到真正需要使用該對象才進行建立和執行個體化。由於一些對象建立和執行個體化需要佔用大量系統資源,但我們並不能確定使用者一定會調用該對象,所以通過延遲物件執行個體化來減緩系統資源的消耗。例如文檔編輯器如word,我們可以在裡面插入連結、圖片等,但是並不是我們每次開啟word時都有建立和執行個體化這些對象,特別是執行個體化圖片對象很消耗資源,而且我們有必要執行個體化所有圖片嗎?當我們在查看word時,只是看到其中的一部分,所以沒有必要執行個體化所以資源,當我們看下一頁時再執行個體化也不遲。例如webservice,當我們訪問網路上一台電腦的資源時,我們正在跨越網路障礙,跨越網路障礙有時候是非常複雜,因為要確保資料安全可靠地傳輸。還好代理模式(Proxy)幫我們解決了其中的一些問題----WebService技術。通過對web的引用,我們可以實現對request和response的簡單操作,這個代理把中間的過程都封裝好了。
另外,在讀取佔用資源比較大的圖片等內容的時候,我們可以先顯示本地的備用圖片,同時通過thread實現http的請求,請求結束後,讓圖片重新整理顯示,於是http作為我們的代理,實現了一些大圖片的延遲顯示。
代理種類:
1.遠程(Remote)代理:
為一個位於不同的地址空間的對象提供一個局域代表對象。這個不同的地址空間可以是在本機器中,也可是在另一台機器中。遠程代理又叫做大使(Ambassador)。
2.虛擬(Virtual)代理:
根據需要建立一個資源消耗較大的對象,使得此對象只在需要時才會被真正建立。
3.Copy-on-Write代理:
虛擬代理的一種。把複製(複製)拖延到只有在用戶端需要時,才真正採取行動。
4.保護(Protect or Access)代理:
控制對一個對象的訪問,如果需要,可以給不同的使用者提供不同層級的使用許可權。
5.Cache代理:
為某一個目標操作的結果提供臨時的儲存空間,以便多個用戶端可以共用這些結果。
6.防火牆(Firewall)代理:
保護目標,不讓惡意使用者接近。
7.同步化(Synchronization)代理:
使幾個使用者能夠同時使用一個對象而沒有衝突。
8.智能引用(Smart Reference)代理:
當一個對象被引用時,提供一些額外的操作,比如將對此對象調用的次數記錄下來等。
何時採用
l代理模式應用非常廣泛,如果你希望降低對象的使用複雜度、或是提升對象使用的友好度、或是提高對象使用的效率都可以考慮代理模式。
在現實生活中也有很多代理的角色,比如明星的經紀人,他就是一種代理,經紀人為明星處理很多對外的事情,目的是為了節省被代理對象也就是明星的時間。保險代理人協助投保人辦理保險,目的降低投保的複雜度。
在開發中代理模式也因為目的不同效果各不相同。比如,如果我們的網站程式是通過.NET Remoting來訪問帳號服務的。在編寫代碼的時候可能希望直接引用帳號服務的DLL,直接執行個體化帳號服務的類型以方便調試。那麼,我們可以引入Proxy模式,做一個帳號服務的代理,網站只需要直接調用代理即可。在代理內部實現正式和測試環境的切換,以及封裝調用.NET Remoting的工作。
代理模式主要用與解決遠端存取的傳輸問題,將複雜的網路傳輸封裝到代理類裡,這樣讓訪問者能像使用本地方法一樣使用代理方法,讓網路對使用者透明。但我認為代理模式遠不止這些應用,只要是封裝了複雜的變化,讓使用者使用方法進一步簡化,都可以稱之為代理。就像我可能根本不懂申請網域名稱需要多少步驟,多說東西,但我知道有做網域名稱代理的公司,直接找到那些公司一切都好說了,代理在我們的生活中是無處不在的。
實現要點
代理對象和被代理對象都遵循一致的介面。
在某些情況下,可以不必保持介面一致性,如果封裝確實需要損失一些透明度,那麼也可以認為是Proxy.
注意事項
Proxy、Facade以及Adapter可能都是對對象的一層封裝,側重點不同。Proxy基於一致的介面進行封裝,Facade針對封裝子系統,轉化為高層介面,而Adapter的封裝是處於適配介面的目的。
代理模式和裝飾者:
意圖:它們都提供間接訪問對象層,都儲存被調用對象的引用。
代理模式(Proxy):為另一個對象提供一個替身或預留位置以控制對這個對象的訪問,簡而言之就是用一個對象來代表另一個對象。
裝飾者(Decorator):動態地給一個對象添加一些額外的職責,就增加功能來說,Decorator模式比產生子類更為靈活,它避免了類爆炸問題,像裝飾者(Decorator),代理模式(Proxy)組成一個對象並提供相同的介面,但代理模式並不關心對象動態職能的增減。
在代理模式(Proxy)中Subject定義了主要的功能,而且Proxy根據Subject提供功能控制對象的存取權限。在裝飾者(Decorator)中Component只是提供了其中的一些功能,需要通過裝飾鏈動態給對象增加職能。
最後,還是像培訓時候的PPT演講一樣,我一直都在談論中國足球,當時教室外面總會有人路過的時候笑我一聲,你看,這兒有談中國足球的呢,其實,對於中超,足協變成這樣那樣,國足能力日趨下降,在我看來,不是球員問題,因為本質都在國家制度,國家對這個運動的普及程度,我們中國可選有很多,不像別的國家一樣,比如韓國,昨晚韓國的男人,生下來不踢足球就不叫男人,比如英國,德國,他們幾乎每個人都有自己信仰的一支足球隊,比如非洲國家,再窮,也會有一個足球伴著孩子們的成長,但在我們中國不是,我們中國不算窮,不算富,我們走的是平庸化,我們一直都在學習,我們可選的目標有很多,可走的運動有很多,而對於足球,從我們的信仰裡,好像早已經被剔除出去了,再談國足或者中超戰績的時候,請國民,請那些自稱為球迷的人,認識到你自己的信仰,你是想在歐洲杯時候跟自己國家的球迷對罵來支援那歐洲的球隊,還是做一個真正的球迷找到自己鐘愛的自己的球隊,找到自己對於國家對於自己國家這項賽事的信仰。
如果你說你是一個真球迷,那麼,請信仰。
(初涉設計模式,希望大家看到不足和缺陷能隨時指出,一起學習一下。。。)
轉載請註明出處:Edward_jie,http://www.cnblogs.com/promise-7/archive/2012/05/25/2518344.html