Sealyu

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

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

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

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

          從擊鼓傳花談起

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

          擊鼓傳花便是責(zé)任鏈模式的應(yīng)用。責(zé)任鏈可能是一條直線、一個(gè)環(huán)鏈或者一個(gè)樹結(jié)構(gòu)的一部分。


          二、 責(zé)任鏈模式的結(jié)構(gòu)

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

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

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



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

          Chain of Responsibility模式的優(yōu)優(yōu)缺點(diǎn):
          優(yōu)點(diǎn):
          1,責(zé)任的分擔(dān)。每個(gè)類只需要處理自己該處理的工作(不該處理的傳遞給下一個(gè)對象完成),明確各類的責(zé)任范圍,符合類的最小封裝原則。
          2,可以根據(jù)需要自由組合工作流程。如工作流程發(fā)生變化,可以通過重新分配對象鏈便可適應(yīng)新的工作流程。
          3,類與類之間可以以松耦合的形式加以組織。
          缺點(diǎn):
          因?yàn)樘幚頃r(shí)以鏈的形式在對象間傳遞消息,根據(jù)實(shí)現(xiàn)方式不同,有可能會影響處理的速度。



          例子:
          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)  編輯  收藏 所屬分類: 設(shè)計(jì)模式
          主站蜘蛛池模板: 牙克石市| 嫩江县| 平阴县| 龙胜| 株洲县| 绥化市| 永顺县| 施秉县| 临夏市| 敦化市| 隆昌县| 兴仁县| 白朗县| 安顺市| 长寿区| 龙川县| 揭东县| 金门县| 巴彦淖尔市| 武宁县| 铅山县| 米脂县| 公安县| 南皮县| 镇雄县| 新巴尔虎左旗| 五台县| 泸西县| 望都县| 鹤山市| 衡水市| 永城市| 雷波县| 融水| 曲沃县| 昆山市| 临澧县| 德江县| 乐至县| 比如县| 巫溪县|