qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          精解Java中代理模式的實現(xiàn)

            簡介摘要: 代理模式是GOF設(shè)計模式中的一種,常用于權(quán)限模塊的架構(gòu)設(shè)計,其根本的原理是通過將一個代理對象交給調(diào)用者,使得調(diào)用者不能直接使用相應(yīng)的功能模塊,所 有的調(diào)用被傳遞給代理對象,代理對象負責(zé)對真實模塊完成調(diào)用,在調(diào)用者與被調(diào)用者之間建立了一個隔離帶,我們可以使 代理模式是GOF設(shè)計模式中的一種,常用于權(quán)限模塊的架構(gòu)設(shè)計,其根本的原理是通過將一個代理對象交給調(diào)用者,使得調(diào)用者不能直接使用相應(yīng)的功能模塊,所有的調(diào)用被傳遞給代理對象,代理對象負責(zé)對真實模塊完成調(diào)用,在調(diào)用者與被調(diào)用者[bei tiao yong zhe]之間建立了一個隔離帶,我們可以使用這個隔離帶進行權(quán)限檢查、對象的延遲[yan chi] 加載等功能的實現(xiàn)。這里不對這個設(shè)計模式的具體原理多加解釋[jie shi],我們直接通過一個實例的編寫來完成對代理模式的應(yīng)用[ying yong],在理解了代理模式之后,我們將繼續(xù)介紹 java中提供的一種動態(tài)[dong tai]代理技術(shù)與其實現(xiàn)。

            這里我們假設(shè)有一個用戶管理模塊,這個模塊提供了添加用戶、刪除用戶的功能。我們現(xiàn)在要使用代理模式來檢查權(quán)限該如何實現(xiàn)呢?首先我們需要具有一個類叫User用來表示一個用戶的信息[xin xi],代碼如下:

        1. public class User { 
        2.        private String username; 
        3.        private String password; 
        4.        public User() { 
        5.        } 
        6.        public User(String username, String password) { 
        7.                this.username = username; 
        8.                this.password = password; 
        9.        } 
        10.  }
        11.   為了提供功能模塊,并且希望能夠隔離模塊,我們需要設(shè)計一個接口來定義用戶管理模塊的接口,這里我們定義IUserFace接口,代碼如下:

        12. public interface IUserFace { 
        13.        public void addUser(User user); 
        14.        public void removeUser(User user); 
        15. }
        16.   接下來為這個接口編寫一個真正實現(xiàn)具體功能的類出來,定義為UserFaceImpl,代碼如下:

        17. public class UserFaceImpl implements IUserFace { 
        18.        public void addUser(User user) { 
        19.                //這里處理相關(guān)的添加用戶的代碼任務(wù) 
        20.                //比如說連接數(shù)據(jù)庫,執(zhí)行相關(guān)的SQL語句 
        21.                System.out.println("Add User Successfully"); 
        22.        } 
        23.        public void removeUser(User user) { 
        24.                //這里處理相關(guān)的刪除用戶的代碼任務(wù) 
        25.                //比如說連接數(shù)據(jù)庫,執(zhí)行相關(guān)的SQL語句 
        26.                System.out.println("Remove User Successfully"); 
        27.        } 
        28. }
        29.   好了,現(xiàn)在我們對外提供的功能具備了,那么使用者該如何使用這個功能的實現(xiàn)類呢?為了讓外界對具體功能類的使用透明化,我們實現(xiàn)一個工廠類來負責(zé)創(chuàng)造具體功能模塊的對象,并以接口的形式提供外界使用,這樣將來更換相關(guān)模塊的使用將會比較方便。具體工廠類(FaceFactory)代碼如下:

        30. public class FaceFactory { 
        31.        private static FaceFactory instance; 
        32.        private FaceFactory() { 
        33.        } 
        34.        public static FaceFactory getInstance() { 
        35.                if(instance == null) { 
        36.                        instance = new FaceFactory(); 
        37.                } 
        38.                return instance; 
        39.        } 
        40.        public IUserFace createUserFace() { 
        41.                return new UserFaceImpl(); 
        42.        } 
        43. }

        44.  完成了工廠類的代碼,我們可以使用具體模塊,這里我們編寫一個App.java來使用以下具體功能模塊,代碼如下:

        45. public class App { 
        46.        public static void main(String args[]) { 
        47.                User u = new User(); 
        48.                IUserFace uf = FaceFactory.getInstance().createUserFace(); 
        49.                uf.addUser(u); 
        50.        } 
        51. }
        52.   從上面代碼我們可以看到,代碼中并沒有提及UserFaceImpl這個類,這保證了將來如果需要跟換UserFaceImpl這個類的使用,調(diào)用者的代碼將不需要做任何的修改。好了,現(xiàn)在我們要來研究一下權(quán)限的問題,在這個例子中,我們可能需要在添加用戶或者刪除用戶的時候進行權(quán)限檢查,符合權(quán)限的才能執(zhí)行相關(guān)動作,否則不能執(zhí)行,那么該如何修改代碼才能更加貼切,而且在實際的編寫過程中,雖然我們需要權(quán)限模塊,但有時候為了更好地快速測試,我們常常希望暫時關(guān)閉權(quán)限模塊,如何才能讓這樣的臨時需求變得更加容易處理呢?我們現(xiàn)在使用代理模式來完成這樣的任務(wù),現(xiàn)在繼續(xù)編寫一個類叫 UserFaceProxy,讓它也實現(xiàn)IUserFace接口,也許你會說,不是已經(jīng)有一個類實現(xiàn)了這個接口了嗎?為什么還要寫一個?不要著急,看完這個代碼,你就會了解其中的道理了。

        53. public class UserFaceProxy implements IUserFace { 
        54.        private IUserFace userFace; 
        55.        public UserFaceProxy(IUserFace userFace) { 
        56.                this.userFace = userFace; 
        57.        } 
        58.        public void addUser(User user) { 
        59.                //在這里檢查權(quán)限,如果權(quán)限不合法則拋出異常
        60.                userFace.addUser(user); 
        61.        } 
        62.        public void removeUser(User user) { 
        63.                //在這里檢查權(quán)限,如果權(quán)限不合法則拋出異常
        64.                //如果權(quán)限通過則完成下面的工作 
        65.                userFace.removeUser(user); 
        66.        } 
        67. }
        68.   在代碼中你可以看到,這個代理類在構(gòu)造對象的時候需要傳入一個實現(xiàn)了IUserFace接口的類的對象,當(dāng)代理類對象的方法被調(diào)用的時候,首先檢查權(quán)限,如果權(quán)限檢查不通過,那么則拋出異常,通過的話則調(diào)用構(gòu)造時傳入對象的相應(yīng)方法]來完成真是的工作。這樣的話,我們需要繼續(xù)修改工廠類的代碼如下:

        69. public class FaceFactory { 
        70.        private static FaceFactory instance; 
        71.        private FaceFactory() { 
        72.        } 
        73.        public static FaceFactory getInstance() { 
        74.                if(instance == null) { 
        75.                        instance = new FaceFactory(); 
        76.                } 
        77.                return instance; 
        78.        } 
        79.        public IUserFace createUserFace() { 
        80.                IUserFace userFace = new UserFaceImpl(); 
        81.                IUserFace proxy = new UserFaceProxy(userFace); 
        82.                return proxy; 
        83.        } 
        84. }
        85.   好了,到這里你是不是已經(jīng)明白了?通過這樣的代理模式我們完成了權(quán)限檢查的隔離處理,當(dāng)需要臨時關(guān)閉權(quán)限檢查的時候,我們只需要在如上的代碼中return userFace;就可以了。這就是代理模式在實際中的應(yīng)用步驟。


          posted on 2011-12-05 13:32 順其自然EVO 閱讀(140) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          <2011年12月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 绥芬河市| 商水县| 林甸县| 宽甸| 视频| 南雄市| 温泉县| 隆化县| 潍坊市| 中山市| 多伦县| 象山县| 凌海市| 东海县| 寿阳县| 溧水县| 介休市| 甘南县| 西城区| 星座| 来宾市| 长葛市| 界首市| 图木舒克市| 文登市| 宝坻区| 罗田县| 安泽县| 武冈市| 吉林市| 英山县| 陵水| 青州市| 大理市| 游戏| 睢宁县| 汤原县| 上栗县| 明光市| 罗田县| 曲阜市|