Facade模式 和 Proxy模式
?Facade简化并提供了对基础架构的统一访问,从而减少复杂性。它只是封装,可以看成黑盒。
在Web编程中,有所谓的n-层架构,就是Facade的思想,即每一层都封装好一部分功能,提供给上一层统一的方法调用,比如说数据层,将操作一次数据库的整个过程封装为一个方法,而我们在逻辑层调用该方法时,只需要传递一个SQL参数:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->????????public?static?void?ExecNonQuery(string ?sql) ????????{? ????????????using?(SqlConnection?conn?=?new ?SqlConnection()) ????????????{ ????????????????conn.Open(); ????????????????SqlCommand?cmd?=?new ?SqlCommand(sql); ????????????????cmd.ExecuteNonQuery();???????????????? ????????????} ????????}
? ? ? ? Facade的定義: 爲子系統中的一組介面提供一個一致的介面。 Facade一個典型應用就是資料庫JDBC的應用,如下例對資料庫的操作:
上例是Jsp中最通常的對資料庫操作辦法。 在應用中,經常需要對資料庫操作,每次都寫上述一段代碼肯定比較麻煩,需要將其中不變的部分提煉出來,做成一個介面,這就引入了facade外觀物件。如果以後我們更換Class.forName中的<driver>也非常方便,比如從Mysql資料庫換到Oracle資料庫,只要更換facade介面中的driver就可以。 我們做成了一個Facade介面,使用該介面,上例中的程式就可以更改如下:
可見非常簡單,所有程式對資料庫訪問都是使用改介面,降低系統的複雜性,增加了靈活性。 如果我們要使用連接池,也只要針對facade介面修改就可以。 ? 由上圖可以看出,facade實際上是個理順系統間關係,降低系統間耦合度的一個常用的辦法,也許你已經不知不覺在使用,儘管不知道它就是facade。 ? ? ? ? ? ? ? ? ? ? ? ? ? Proxy :----------------------------------------------- ? ? ? 这个模式用途很多,先看它的UML: ? ? ?Client端使用如下: ? ? ????加载大图片: ? 在Client端调用方法: ? ? 注意这句话:???????????? 原有系统的方法GetDisCount(),只有Role=管理员时才可以调用。 ? ? 现在要直接使用这个方法,而跳过权限控制,可以从中派生出一个子类ProxyCompDiscount: ? 以上是去除多余的权限,相当于短路操作。反之,也可以使用同样的方法,增加权限。 ? ? 在Client端,Proxy模式不用知道被代理的对象;而Decorator模式需要知道被修饰的对象。这是二者的区别 ? ? ? ? ? ? ? ? ? ? ? ? ? 理解並使用設計模式,能夠培養我們良好的面向物件編程習慣,同時在實際應用中,可以如魚得水,享受遊刃有餘的樂趣。 Proxy是比較有用途的一種模式,而且變種較多,應用場合覆蓋從小結構到整個系統的大結構,Proxy是代理的意思,我們也許有代理伺服器等概念,代理概念可以解釋爲:在出發點到目的地之間有一道中間層,意爲代理。 設計模式中定義: 爲其他物件提供一種代理以控制對這個物件的訪問。 爲什麽要使用Proxy? 2.某個用戶端不能直接操作到某個物件,但又必須和那個物件有所互動。 總之原則是,對於開銷很大的物件,只有在使用它時才創建,這個原則可以爲我們節省很多寶貴的Java記憶體。 所以,有些人認爲Java耗費資源記憶體,我以爲這和程式編制思路也有一定的關係。 如何使用Proxy? Forum是Jive的核心介面,在Forum中陳列了有關論壇操作的主要行爲,如論壇名稱 論壇描述的獲取和修改,帖子發表刪除編輯等。 在ForumPermissions中定義了各種級別許可權的用戶:
因此,Forum中各種操作許可權是和ForumPermissions定義的用戶級別有關係的,作爲介面Forum的實現:ForumProxy正是將這種對應關係聯繫起來。比如,修改Forum的名稱,只有論壇管理者或系統管理者可以修改,代碼如下:
而DbForum才是介面Forum的真正實現,以修改論壇名稱爲例:
凡是涉及到對論壇名稱修改這一事件,其他程式都首先得和ForumProxy打交道,由ForumProxy決定是否有許可權做某一樣事情,ForumProxy是個名副其實的"閘道","安全代理系統"。 在平時應用中,無可避免總要涉及到系統的授權或安全體系,不管你有無意識的使用Proxy,實際你已經在使用Proxy了。 我們繼續結合Jive談入深一點,下面要涉及到工廠模式了,如果你不瞭解工廠模式,請看我的另外一篇文章:設計模式之Factory 我們已經知道,使用Forum需要通過ForumProxy,Jive中創建一個Forum是使用Factory模式,有一個總的抽象類別ForumFactory,在這個抽象類別中,呼叫ForumFactory是通過getInstance()方法實現,這裏使用了Singleton(也是設計模式之一,由於介紹文章很多,我就不寫了,看這裏),getInstance()返回的是ForumFactoryProxy。 爲什麽不返回ForumFactory,而返回ForumFactory的實現ForumFactoryProxy? 在ForumFactoryProxy中我們看到代碼如下:
方法createForum返回的也是ForumProxy,Proxy就象一道牆,其他程式只能和Proxy交互操作。 注意到這裏有兩個Proxy:ForumProxy和ForumFactoryProxy。 代表兩個不同的職責:使用Forum和創建Forum; Jive論壇系統中其他如帖子的創建和使用,都是按照Forum這個思路而來的。 以上我們討論了如何使用Proxy進行授權機制的訪問,Proxy還可以對用戶隱藏另外一種稱爲copy-on-write的優化方式。拷貝一個龐大而複雜的物件是一個開銷很大的操作,如果拷貝過程中,沒有對原來的物件有所修改,那麽這樣的拷貝開銷就沒有必要。用代理延遲這一拷貝過程。 比如:我們有一個很大的Collection,具體如hashtable,有很多用戶端會並發同時訪問它。其中一個特別的用戶端要進行連續的資料獲取,此時要求其他用戶端不能再向hashtable中增加或刪除 東東。 最直接的解決方案是:使用collection的lock,讓這特別的用戶端獲得這個lock,進行連續的資料獲取,然後再釋放lock。 } 但是這一辦法可能鎖住Collection會很長時間,這段時間,其他用戶端就不能訪問該Collection了。 第二個解決方案是clone這個Collection,然後讓連續的資料獲取針對clone出來的那個Collection操作。這個方案前提是,這個Collection是可clone的,而且必須有提供深度clone的方法。Hashtable就提供了對自己的clone方法,但不是Key和value物件的clone,關於Clone含義可以參考專門文章。 Hashttable newht=(Hashtable)ht.clone(); } 問題又來了,由於是針對clone出來的物件操作,如果原來的母體被其他用戶端操作修改了,那麽對clone出來的物件操作就沒有意義了。 最後解決方案:我們可以等其他用戶端修改完成後再進行clone,也就是說,這個特別的用戶端先通過呼叫一個叫clone的方法來進行一系列資料獲取操作。但實際上沒有真正的進行物件拷貝,直至有其他用戶端修改了這個物件Collection。 使用Proxy實現這個方案。這就是copy-on-write操作。 Proxy應用範圍很廣,現在流行的分佈計算方式RMI和Corba等都是Proxy模式的應用。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |