Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks

          一、 職責鏈(Chain of Responsibility)模式

          責任鏈模式是一種對象的行為模式【GOF95】。在責任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞, 直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新 組織鏈和分配責任。

          從擊鼓傳花談起

          擊鼓傳花是一種熱鬧而又緊張的飲酒游戲。在酒宴上賓客依次坐定位置,由一人擊鼓,擊鼓的地方與傳花的地方是分開的,以示公正。開始擊鼓時,花束就開始依次傳遞,鼓聲一落,如果花束在某人手中,則該人就得飲酒。

          擊鼓傳花便是責任鏈模式的應用。責任鏈可能是一條直線、一個環鏈或者一個樹結構的一部分。


          二、 責任鏈模式的結構

          責任鏈模式涉及到的角色如下所示:

          抽象處理者(Handler)角色:定義出一個處理請求的接口。如果需要,接口可以定義出一個方法,以設定和返回對下家的引用。這個角色通常由一個抽象類或接口實現。

          具體處理者(ConcreteHandler)角色:具體處理者接到請求后,可以選擇將請求處理掉,或者將請求傳給下家。由于具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。



          Chain of Responsibility模式的實現
          要實現Chain of Responsibility模式,需要滿足該模式的基本要件:
          1,對象鏈的組織。需要將某任務的所有職責執行對象以鏈的形式加以組織。
          2,消息或請求的傳遞。將消息或請求沿著對象鏈傳遞,以讓處于對象鏈中的對象得到處理機會。
          3,處于對象鏈中的對象的職責分配。不同的對象完成不同的職責。
          4,任務的完成。處于對象鏈的末尾的對象結束任務并停止消息或請求的繼續傳遞。

          Chain of Responsibility模式的優優缺點:
          優點:
          1,責任的分擔。每個類只需要處理自己該處理的工作(不該處理的傳遞給下一個對象完成),明確各類的責任范圍,符合類的最小封裝原則。
          2,可以根據需要自由組合工作流程。如工作流程發生變化,可以通過重新分配對象鏈便可適應新的工作流程。
          3,類與類之間可以以松耦合的形式加以組織。
          缺點:
          因為處理時以鏈的形式在對象間傳遞消息,根據實現方式不同,有可能會影響處理的速度。



          例子:
          namespace ChainOfResponsibility_DesignPattern
          {
              
          using System;

              
          abstract class Handler 
              {
                  
          protected Handler successorHandler;
                  
          abstract public void HandleRequest(Request request);        
                  
          public void SetSuccessor(Handler sucessor)
                  {
                      successorHandler 
          = sucessor;
                  }
              }

              
          class ConcreteHandler1 : Handler
              {
                  
          override public void HandleRequest(Request request)
                  {
                      
          // determine if we can handle the request
                      if (request.RequestType == 1// some complex decision making!
                      {
                          
          // request handling code goes here
                          Console.WriteLine("request handled in ConcreteHandler1");
                      }
                      
          else 
                      {
                          
          // not handled here - pass on to next in the chain
                          if (successorHandler != null)
                              successorHandler.HandleRequest(request);
                      }
                  }
              }

              
          class ConcreteHandler2 : Handler
              {
                  
          override public void HandleRequest(Request request)
                  {
                      
          // determine if we can handle the request
                      if (request.RequestType == 2// some complex decision making!
                      {
                          
          // request handling code goes here
                          Console.WriteLine("request handled in ConcreteHandler2");
                      }
                      
          else 
                      {
                          
          // not handled here - pass on to next in the chain
                          if (successorHandler != null)
                              successorHandler.HandleRequest(request);
                      }
                  }
              }

              
          class ConcreteHandler3 : Handler
              {
                  
          override public void HandleRequest(Request request)
                  {
                      
          // determine if we can handle the request
                      if (request.RequestType == 3// some complex decision making!
                      {
                          
          // request handling code goes here
                          Console.WriteLine("request handled in ConcreteHandler3");
                      }
                      
          else 
                      {
                          
          // not handled here - pass on to next in the chain
                          if (successorHandler != null)
                              successorHandler.HandleRequest(request);
                      }        
                  }
              }

              
          class Request 
              {
                  
          private int iRequestType;
                  
          private string strRequestParameters;

                  
          public Request(int requestType, string requestParameters)
                  {
                      iRequestType 
          = requestType;    
                      strRequestParameters 
          = requestParameters;
                  }

                  
          public int RequestType 
                  {
                      
          get 
                      {
                          
          return iRequestType;
                      }
                      
          set 
                      {
                          iRequestType 
          = value;
                      }
                  }
              }

              
          /// <summary>
              
          ///    Summary description for Client.
              
          /// </summary>
              public class Client
              {
                  
          public static int Main(string[] args)
                  {
                      
          // Set up chain (usually one need to be done once)
                      Handler firstHandler = new ConcreteHandler1();
                      Handler secondHandler 
          = new ConcreteHandler2();
                      Handler thirdHandler 
          = new ConcreteHandler3();
                      firstHandler.SetSuccessor(secondHandler);
                      secondHandler.SetSuccessor(thirdHandler);

                      
          // After setting up the chain of responsibility, we can
                      
          // now generate requests and pass then off to the 
                      
          // chain to be handled

                      
          // generate and fire request
                      Request newRequest = new Request(2,"This are the request parameters");
                      firstHandler.HandleRequest(newRequest);
                      
                      
          return 0;
                  }
              }
          }


          posted on 2009-12-23 15:09 seal 閱讀(412) 評論(0)  編輯  收藏 所屬分類: 設計模式
          主站蜘蛛池模板: 乌鲁木齐市| 嘉义市| 合水县| 西充县| 贡嘎县| 阳东县| 辉南县| 湄潭县| 福州市| 涟源市| 黑龙江省| 广饶县| 沅江市| 施秉县| 巫溪县| 文山县| 鹤山市| 利津县| 沅江市| 齐齐哈尔市| 甘洛县| 南雄市| 富裕县| 芒康县| 玉山县| 博野县| 乐陵市| 淮安市| 册亨县| 金山区| 北海市| 内丘县| 金华市| 涪陵区| 廊坊市| 宝丰县| 宜宾市| 莎车县| 北川| 当涂县| 定远县|