閱讀189 返回首頁    go 阿裏雲 go 技術社區[雲棲]


設計模式之代理模式

        最近《軟件體係/設計模式》要匯報代理模式,查找了很多代理模式的資料,整理了下麵的一些關於代理模式的文章.
        (鐵血肯德基-Eastmount 製作)

一.模式產生的原因
        在麵向對象係統中,有些對象由於某些原因,比如:對象開銷太大、某些操作需要安全控製、或者要訪問的對象在遠程的機器上,直而采用接訪問會給使用者或係統結構帶來很多麻煩。
        現在,我們可以在訪問此對象時添加一個對此對象的訪問層——代理。
        例如:Web安全課程中講述的瀏覽網頁的代理工具WebScarab、購買火車票時的代售點、銀行交易支付的支付寶等。
上麵這些例子都用到了代理的概念,那麼究竟什麼是代理模式呢?
二.模式的定義和結構
        模式定義
        代理模式(Proxy Pattern/Surrogat):給某一個對象提供一個代理,並由代理對象控製對原對象的引用。代理模式是一種對象結構模式。
        簡而言之:一個客戶不想或者不能直接引用一個對象,此時可以通過代理的第三者來實現間接引用,代理對象可以在客戶端目標對象之間起到中介作用,可以通過代理對象去掉客戶不能看到的內容和服務或者添加客戶需要的額外服務.
        下麵是一張代理模式的JAVA結構圖:

        代理模式結構圖簡化為如下:

        代理模式抽象成類並設立一些方法後的結構圖為:

        代理模式包含如下角色:
        Proxy:代理主題角色.內容包含對真實主題的引用,並提供了與真實主題角色相同的接口,以便在任何時候都可以替代真實主題.
        Subject:抽象主題角色.聲明真實主題和代理主題的共同接口,這樣可以在任何使用真實主題的地方可以使用代理主題.
        RealSubject:真實主題角色.定義真實的對象.
        上麵是代理模式的3個角色,下麵介紹代理模式的常見幾種模式及分類.
三.常見代理模式 
        根據《Java與模式書中對代理模式的分類,代理模式分為8種,這裏將幾種常見的、重要的列舉如下:
        1.遠程(Remote)代理:為一個位於不同的地址空間的對象提供一個局域代表對象。比如:你可以將一個在世界某個角落一台機器通過代理假象成你局域網中的一部分。
        2.虛擬Virtual)代理:根據需要將一個資源消耗很大或者比較複雜的對象延遲的真正需要時才創建。比如:如果一個很大的圖片,需要花費很長時間才能顯示出來,那麼當這個圖片包含在文檔中時,使用編輯器或瀏覽器打開這個文檔,這個大圖片可能就影響文檔的閱讀,這時需要做個圖片Proxy來代替真正的圖片。
        3.保護Protector Access)代理:控製對一個對象的訪問權限。比如:在論壇中,不同的身份登陸,擁有的權限是不同的,使用代理模式可以控製權限(當然,使用別的方式也可以實現)。
        4.智能引用(SmartReference)代理:提供比對目標對象額外的服務。比如:紀錄訪問的流量(這是個再簡單不過的例子),提供一些友情提示等等
        5.動態(DynamicProxy)代理:較為高級的代理模式,InvocationHandler接口和Proxy(動態代理類).
這裏就不詳細介紹各種代理模式分類了,詳見設計模式書中.其中動態代理是較為特殊的代理模式.
四.實例分析

        實例一:男孩女孩
        一個男孩boy喜歡上了一個女孩girl,男孩一直想認識女孩,直接去和女孩打招唿吧,又覺得不好意思。於是男孩想出了一個辦法,委托女孩的室友Proxy去幫他搞定這件事(獲得一些關於女孩的信息,QQ、手機號、人人號等,
        其結構圖為:

        它的抽象主題角色是GirlInfo,代理主題角色是Proxy,真實主題角色是Girl,通過Client實例化.代碼實現如下:

         實例二:論壇
         在論壇中已注冊用戶和遊客的權限不同,已注冊的用戶擁有發帖,修改自己的注冊信,修改自己的帖子等功能;而遊客隻能看到別人發的帖子,沒有其他權限.為了簡化代碼,更好的顯示出代理模式的骨架,我們這裏隻實現發帖權限的控製.
         其結構圖為:

        它的抽象主題角色是MyForum,代理主題角色是MyForumProxy,真實主題角色是MyForumReal.代碼實現如下:

五.代理模式的優點
         分析問題:
         (1).當我們在網站上瀏覽圖文信息時,進場使用代理模式,訪問網頁時調用的不是真實裝載的圖片,而是在代理對象方法中先使用一個線程向瀏覽器裝載一個縮小的圖片.
        如果要仔細查看這個圖片,則點擊縮小的圖片(代理圖片)並調用響應的方法,在後台使用一個線程來調用真實的裝載大圖片的方法將圖片加載到本地,並在網頁中顯示出來.
        這就一個通過代理模式實現圖片的加載放在後台操作,使其不影響前台的瀏覽.
        (2).遠程代理可以將網絡的細節隱藏起來,使得客戶端不必考慮網絡的存在,使計算機具有更快的響應和處理速度.

        綜上所述:
        代理模式的常見優點如下:
        1.代理模式能夠協調調用者和被調用者,在一定程度上降低了係統的耦合度;加載圖片中後台操作不影響前台效果;
        2.在遠程代理中使得客戶端可以訪問在遠程機器上的對象,遠程機器具有更好的計算性能和處理速度,響應客戶端請求;
        3.代理模式通過使用一個小對象來替代一個大對象,以減少係統資源的消耗,對係統進行優化並提高運行速度,主要表現在虛擬代理;
        4.保護代理可以控製對真實對象的使用權限;
        5.copy-on-write可以大幅度的降低拷貝龐大實體時的開銷. 

六.代理模式的缺點
        1.由於在客戶端和真實主題之間增加代理對象,因此有些類型的代理模式可能會造成請求的處理速度慢;
        2.實現代理模式需要額外的工作,有些代理模式的實現非常複雜;
        3.如果是一個很小的係統,功能也不是很繁雜,那麼使用代理模式可能就顯得臃腫
,需要修改原有的方法.
七.總結
        代理模式是一個常用的模式,代理模式能夠協調調用者和被調用者,能夠在一定程度上降低係統的耦合度在項目中比如打開網頁中的圖片縮略圖,遠程管理係統都經常使用到代理模式。當我們直接訪問一個對象很困難,或者說不能訪問,此時隻能是找個代理去訪問,然後把結果反饋給自己。代理模式中各種分類這裏就不具體介紹它們的實現代碼和實例了.想學習的同學建議看看清華大學出版社劉偉編寫的代理模式書及課件.
        最後說明一下,該文章的知識來自於:自己的分析與理解,《大話設計模式》,《Head First 設計模式》,還有清華大學出版社劉偉編寫的相關課件,還有3個博客的相關閱讀.建議可以看看下麵的3個作者的理解.
        https://tech.ddvip.com/2008-10/122362574376324.html
        https://blog.csdn.net/hguisu/article/details/7542143
        https://blog.csdn.net/ai92/article/details/216424
        在這裏感謝上麵所有的書籍,課件,博主.由於作者才接觸CSDN博客,可能格式內容不是很好,還請海涵!文章中有不足之處或錯誤的地方,作者能力有限,請見諒.希望文章能幫助大家更好的了解代理模式.(鐵血肯德基-Eastmount製作)

最後更新:2017-04-03 20:51:32

  上一篇:go 圖解git中的最常用命令
  下一篇:go Java Socket 網絡編程常見異常