qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          跟屌絲大哥學習設計模式---代理模式

          Java 代理模式詳解

          代理模式是我們比較常用的設計模式之一。其中新思想是為了提供額外的處理或者不同的操作而在實際對象與調用者之間插入一個代理對象。這些額外的操作通常需要與實際對象進行通信,代理模式一般涉及到的角色有: 

          抽象角色:聲明真實對象和代理對象的共同接口; 

          代理角色:代理對象角色內部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象可以在執行真實對象操作時,附加其他的操作,相當于對真實對象進行封裝。 

          真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。

           

          以下以發送消息為例來說明一個簡單的代理模式的基本實現:

          首先明確目的:有一條消息,需要把這個消息發送出去,根據這個目的定義對應接口MessageHandler。需要的附加操作:假設需要驗證消息的長度不能超過指定長度并且不能為空,并且我們需要統計相關信息發送到次數,超過指定的次數我們需要輸出警報。我們通過代理模式來實現這個附加的操作。下面為對應的類關系圖及示例代碼。




          //接口定義
          public interface MessageHandler {
          public void sendMessage(String msg);
          }
          //通過Email方式發送消息的實現類
          public class EmailMessage implements MessageHandler {
          @Override
          public void sendMessage(String msg) {
          // TODO Auto-generated method stub
          System.out.println(msg+" send!!");
          }
          }
          //消息處理的代理類
          public class MessageProxy implements MessageHandler {
          private static int count;
          private MessageHandler emailMsg;
          @Override
          public void sendMessage(String msg) {
          // TODO Auto-generated method stub
          if(checkMessage(msg))
          {
          if(emailMsg==null) emailMsg=new EmailMessage();
          count++;
          emailMsg.sendMessage(msg);
          System.out.println("Message sent:"+count);
          }
          }
          private boolean checkMessage(String msg) {
          return msg != null && msg.length() > 10;
          }
          }
          //調用類
          public class MainClass {
          private static void runProxy(MessageHandler handler)
          {
          handler.sendMessage("message for test");
          }
          /**
           * @param args
           */
          public static void main(String[] args) {
          // TODO Auto-generated method stub
          runProxy(new EmailMessage());
          System.out.println("++++++++++++++++Pjroxy++++++++++++++++++");
          runProxy(new MessageProxy());
          }
          }
          輸出
          message for test send!!
          ++++++++++++++++Pjroxy++++++++++++++++++
          message for test send!!
          Message sent:1

          在例子中我們可以方便的在消息發送過程中添加各種需要的附加處理方式,也能方便的替換消息的處理方式,如將通過Email發送消息替換為通過短信發送消息,而調用方不會有絲毫察覺!在任何你想要將一些額外操作分離到具體對象之外,特別是希望能夠很容易做出修改,或者想在具體對象的方法執行前插入一些額外操作的時候,代理就顯得十分有用!

           例如:假設有一組對象都實現同一個接口,實現同樣的方法,但這組對象中有一部分對象需要有單獨的方法,傳統的笨辦法是在每一個應用端都加上這個單獨的方法,但是代碼重用性低,耦合性高。   如果用代理的方法則很好的解決了這個問題
           假設有一個Italk接口,有空的方法talk()(說話),所有的people對象都實現(implements)這個接口,實現talk()方法, 前端有很多地方都將people實例化,執行talk方法,后來發現這些前端里有一些除了要說話以外還要唱歌(sing),那么我們既不能在Italk接 口里增加sing()方法,又不能在每個前端都增加sing方法,我們只有增加一個代理類talkProxy,這個代理類里實現talk和sing方法, 然后在需要sing方法的客戶端調用代理類即可,代碼如下:

          接口類Italk

            public interface Italk {
            public void talk(String msg);
            }

          實現類people

            public class People implements Italk
           {   public String username;  
           public String age;  
           public String getName()
          {   
          return username;
            }   
          public void setName(String name) {
            this.username= name;   
          }  
           public String getAge() {  
           return age;   }   
          public void setAge(String age) {
            this.age = age;   }  
           public People(String name1, String age1) {
            this.username= name1;  
           this.age = age1;  
           }
            public void talk(String msg) {
            System.out.println(msg+"!你好,我是"+username+",我年齡是"+age);
            }   
          }

          代理類talkProxy

            public class TalkProxy implements Italk
           {   Italk talker;  
           public TalkProxy (Italk talker)
          {
            //super();   
          this.talker=talker;  
           }   
          public void talk(String msg)
          {   
          talker.talk(msg);  
           }   
          public void talk(String msg,String singname)
           {   
          talker.talk(msg);
            sing(singname);
            }   
          private void sing(String singname)
          {  
           System.out.println("唱歌:"+singname);
            }  
           }
            }

          應用端myProxyTest

            public class MyProxyTest {  
           /**代理模式   * @param args   */  
           public static void main(String[] args)
           {   
          //不需要執行額外方法的  
           Italk people1=new People(" people1.talk("No ProXY Test");  
           System.out.println("-----------------------------");  
           //需要執行額外方法的   
          TalkProxy talker=new TalkProxy(people1);   
          talker.talk("ProXY Test","七里香");
            }  
           }
          所謂代理,是指具有與代理元(被代理的對象)具有相同的接口的類,客戶端必須通過代理與被代 理的目標類交互,而代理一般在交互的過程中(交互前后),進行某些特別的處理。Proxy模式是很常見的模式,在我們生活中處處可見,例如我們買火車票不 一定非要到火車站去買,可以到一些火車票的代售點去買。寄信不一定是自己去寄,可以把信委托給郵局,由郵局把信送到目的地。

          代理結構如下圖所示

          Java 代理/動態代理模式(Proxy) - stevinzhu - stevinzhu的博客

          以通過代售點買火車票為例,代碼實現如下:

          //提供買票的公共接口
          interface Passenger {
          public void buyTicket();
          }

          //乘客實體
          public class RealPassenger implements Passenger {
          @Override
          public void buyTicket() {
             // TODO Auto-generated method stub
             System.out.print("購買了火車票");
          }
          }

          //代售點
          public class Proxy implements Passenger {
          Passenger passenger;

          public Proxy(Passenger p) {
             this.passenger = p;
          }

          @Override
          public void buyTicket() {
             // TODO Auto-generated method stub
             System.out.println("通過代售點");
             passenger.buyTicket();
          }
          }

          //測試類
          public class Client {
          public static void main(String[] args) {
             Passenger passenger = new RealPassenger();
             Passenger proxy = new Proxy(passenger);
             proxy.buyTicket();
          }
          }

          輸出結果:
          通過代售點
          購買了火車票

          以 上的也可叫做靜態代理,是為了區別代理模式在Java中的另一種實現——動態代理。

          接下來會為大家帶來動態代理

          posted on 2012-12-13 11:20 順其自然EVO 閱讀(425) 評論(0)  編輯  收藏 所屬分類: 設計模式學習

          <2012年12月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 银川市| 同心县| 镇原县| 左云县| 兴业县| 甘孜县| 滕州市| 自贡市| 安仁县| 凌海市| 舞钢市| 和平区| 桦甸市| 广东省| 白河县| 公安县| 崇州市| 玉山县| 通道| 融水| 洛隆县| 永德县| 那坡县| 大宁县| 布尔津县| 轮台县| 阳山县| 琼海市| 桦川县| 伊吾县| 荆州市| 禄丰县| 阜阳市| 甘谷县| 乌兰浩特市| 阳东县| 乐至县| 新乐市| 乾安县| 西充县| 上栗县|