posts - 262,  comments - 221,  trackbacks - 0

          前面我們看了Decorator模式的一下理論基礎,知道了Decorator模式的適應場合是:在運行時刻由用戶動態決定加入的方式和時機,無法在編譯期間決定。下面我們就以一個實際的例子來了解一下Decorator模式的實際應用。

          一、應用場景:

          假設我們已經存在這樣的一個程序:

          1).該程序從一個列表中拿出所有的用戶名單,然后逐個向用戶發送一句信息。
          2).現在我們又增加了一個新的需求:在發送之前檢查一下該用戶是否存在于黑名單中,如果是的話則不發送給該用戶。
          3).是否進行檢查則動態根據用戶的當時需要來決定。

          二、需求分析:

          從上面的情況分析,如果我們采用繼承的方式,重新編寫一個帶有過濾功能的發送程序,則必須完全改寫原有的發送方法,插入過濾的過程。如果我們采用Decorator模式的話,可以怎么做呢?

          首先分析一下需求的公共部分,相同的部分都是發送信息,不管是否需要進行過濾。也就是說只有發送的方法拿到數據,它就不管三七二十一發出去了,所以這個功能應該可以被抽象成一個接口。

          接下來我們來看一下,既然新的功能只是在舊的功能之前插入了“過濾”這一簡單的過程,原有的功能保持不變,所以我們完全可以把舊的功能委托給老的程序來進行。既然是委托了那么必然在新的類里面要含有一個舊的對象的引用。

          最后如何實現“動態插入過濾功能”呢?我們看一下前面的接口,如果我們實現了接口,那么在其實現方法中就可以重寫原來的方法,增加過濾功能了。

          三、系統設計:

          我們來看一下下面這張圖,明確一下各個對象之間的聯系





          在這張圖中我們看到:我們抽象出了一個接口:ISendMessage接口,原有的SendMessageImpl類和新增的SendMessageDecorator類都實現了該接口。Decorator類有一個對SendMessageImpl的委托。

          四、詳細代碼:

          ·ISendMessage:

          package org.pattern.decorator;

          public interface ISendMessage {

              
          public void send();
          }


          ·SendMessageImpl:

          package org.pattern.decorator;

          import java.util.ArrayList;
          import java.util.Iterator;
          import java.util.List;

          public class SendMessageImpl implements ISendMessage {

              List
          <String> users = new ArrayList<String>();
              
              
          public void setUsers(List<String> users) {
                  
          this.users = users;
              }


              
          public List<String> getUsers() {
                  
          return users;
              }


              
          // Implement
              public void send() {
                  
          for (Iterator it = users.iterator(); it.hasNext();) {
                      String user 
          = (String) it.next();
                      System.out.println(
          "This is for your message : " + user);
                  }

              }


          }


          ·SendMessageDecorator:

          package org.pattern.decorator;

          import java.util.ArrayList;
          import java.util.Iterator;
          import java.util.List;

          public class SendMessageDecorator implements ISendMessage {

              
          private ISendMessage isendMessage;

              
          private boolean filter = false;

              
          private List<String> blackUsers = new ArrayList<String>();
              
              
          // Constructor method
              public SendMessageDecorator(ISendMessage isendMessage){
                  
          this.isendMessage = isendMessage;
              }


              
          // Constructor method with filter flag and black user list
              public SendMessageDecorator(ISendMessage isendMessage, boolean filter,
                      List
          <String> blackUsers) {
                  this.isendMessage = isendMessage;
                  this.filter = filter;
                  
          this.blackUsers = blackUsers;
              }


              
          // Decorator operation: dynamicly add filter logic if needed
              public void send() {
                  
          if (!filter) {
                      isendMessage.send();
                  }
           else {
                      filter(blackUsers);
                      isendMessage.send();
                  }

              }


              
          private void filter(List<String> blackUsers) {
                  
          // Return if black users list is null
                  if (blackUsers == null{
                      
          return;
                  }

                  
          // Remove all users which mattch the black list
                  List users = ((SendMessageImpl) isendMessage).getUsers();
                  List
          <String> newList = new ArrayList<String>();
                  
          for (Iterator it = users.iterator(); it.hasNext();) {
                      String user 
          = (String) it.next();
                      
          if (!blackUsers.contains(user)) {
                          newList.add(user);    
                      }

                  }

                  ((SendMessageImpl)isendMessage).setUsers(newList);
              }


          }


          ·DecoratorTest:

          package org.pattern.decorator;

          import java.util.ArrayList;
          import java.util.List;

          public class DecoratorTest {

              
          public static void main(String args[]) {
                  DecoratorTest dt 
          = new DecoratorTest();
                  dt.test(args[
          0]);    
              }


              
          private void test(String arg) {
                  
          // Create users
                  List<String> users = new ArrayList<String>();
                  users.add(
          "Paul");
                  users.add(
          "Bob");
                  users.add(
          "Tom");
                  users.add(
          "Jim");
                  
          // Set users
                  SendMessageImpl sender = new SendMessageImpl();
                  sender.setUsers(users);
                  
          // Create Decorator
                  if (arg == null || arg.trim().length() == 0 || arg.equalsIgnoreCase("no")) {
                      ISendMessage decorator 
          = new SendMessageDecorator(sender);
                      decorator.send();
                  }
           else {
                      List
          <String> blackUsers = new ArrayList<String>();
                      blackUsers.add(
          "Tom");
                      blackUsers.add(
          "Jim");
                     ISendMessage decorator = new SendMessageDecorator(sender, true,
                              blackUsers);
                      decorator.send();

                  }

              }


          }


          五、Decorator模式的特點:

          A. Decorator類實現了接口(抽象)
          B. Decorator類中包含一個接口類型的屬性,并通過適當的方式被實例化
          C. Decorator類中實現接口的抽象方法,委托父類屬性完成基本功能,同時加入額外功能或改變工作流



          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2008-02-19 18:31 Paul Lin 閱讀(1778) 評論(0)  編輯  收藏 所屬分類: 模式與重構
          <2008年2月>
          272829303112
          3456789
          10111213141516
          17181920212223
          2425262728291
          2345678

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 芜湖市| 阜宁县| 凤城市| 桂阳县| 桂东县| 青河县| 肇庆市| 安西县| 博客| 义乌市| 云安县| 壤塘县| 彝良县| 资中县| 巩留县| 台中县| 苗栗县| 潼关县| 会泽县| 凤凰县| 永春县| 土默特左旗| 双柏县| 金川县| 镇平县| 白山市| 定西市| 华安县| 乐都县| 泰兴市| 饶阳县| 叙永县| 罗城| 龙南县| 固安县| 三门县| 衡山县| 象州县| 淳化县| 屯昌县| 湄潭县|