隨筆 - 6, 文章 - 1, 評論 - 13, 引用 - 0
          數據加載中……

          職責鏈(Chain of Responsibility)模式

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

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

          從擊鼓傳花談起

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

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



          二、 責任鏈模式的結構

           

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

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

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


          三、 責任鏈模式的示意性源代碼

           

          // Chain of Responsibility pattern -- Structural example  
          using System;

          // "Handler"
          abstract class Handler
          {
            
          // Fields
            protected Handler successor;
           
            
          // Methods
            public void SetSuccessor( Handler successor )
            
          {
              
          this.successor = successor;
            }

            
          abstract public void HandleRequest( int request );
          }


          // "ConcreteHandler1"
          class ConcreteHandler1 : Handler
          {
            
          // Methods
            override public void HandleRequest( int request )
            
          {
              
          if( request >= 0 && request < 10 )
                Console.WriteLine(
          "{0} handled request {1}",
                  
          this, request );
              
          else
                
          if( successor != null )
                successor.HandleRequest( request );
            }

          }


          // "ConcreteHandler2"
          class ConcreteHandler2 : Handler
          {
            
          // Methods
            override public void HandleRequest( int request )
            
          {
              
          if( request >= 10 && request < 20 )
                Console.WriteLine(
          "{0} handled request {1}",
                  
          this, request );
              
          else
                
          if( successor != null )
                successor.HandleRequest( request );
            }

          }


          // "ConcreteHandler3"
          class ConcreteHandler3 : Handler
          {
            
          // Methods
            override public void HandleRequest( int request )
            
          {
              
          if( request >= 20 && request < 30 )
                Console.WriteLine(
          "{0} handled request {1}",
                  
          this, request );
              
          else
                
          if( successor != null )
                successor.HandleRequest( request );
            }

          }


          /// <summary>
          /// Client test
          /// </summary>

          public class Client
          {
            
          public static void Main( string[] args )
            
          {
              
          // Setup Chain of Responsibility
              Handler h1 = new ConcreteHandler1();
              Handler h2 
          = new ConcreteHandler2();
              Handler h3 
          = new ConcreteHandler3();
              h1.SetSuccessor(h2);
              h2.SetSuccessor(h3);

              
          // Generate and process request
              int[] requests = 2514221832720 };

              
          foreachint request in requests )
                h1.HandleRequest( request );

            }

          }

           

           


          四、 純的與不純的責任鏈模式

          一個純的責任鏈模式要求一個具體的處理者對象只能在兩個行為中選擇一個:一個是承擔責任,二是把責任推給下家。不允許出現某一個具體處理者對象在承擔了一部分責任后又把責任向下傳的情況。

          在一個純的責任鏈模式里面,一個請求必須被某一個處理者對象所接收;在一個不純的責任鏈模式里面,一個請求可以最終不被任何接收端對象所接收。純的責任鏈模式的例子是不容易找到的,一般看到的例子均是不純的責任鏈模式的實現。


          五、 責任鏈模式的實際應用案例

          下面的責任鏈模式代碼演示了不同職務的人根據所設定的權限對一個購買請求作出決策或將其交給更高的決策者。

           

          // Chain of Responsibility pattern -- Real World example  
          using System;

          // "Handler"
          abstract class Approver
          {
            
          // Fields
            protected string name;
            
          protected Approver successor;

            
          // Constructors
            public Approver( string name )
            
          {
              
          this.name = name;
            }


            
          // Methods
            public void SetSuccessor( Approver successor )
            
          {
              
          this.successor = successor;
            }


            
          abstract public void ProcessRequest( PurchaseRequest request );
          }


          // "ConcreteHandler"
          class Director : Approver
          {
            
          // Constructors
            public Director ( string name ) : base( name ) {}

            
          // Methods
            override public void ProcessRequest( PurchaseRequest request )
            
          {
              
          if( request.Amount < 10000.0 )
                Console.WriteLine( 
          "{0} {1} approved request# {2}",
                  
          this, name, request.Number);
              
          else
                
          if( successor != null )
                successor.ProcessRequest( request );
            }

          }


          // "ConcreteHandler"
          class VicePresident : Approver
          {
            
          // Constructors
            public VicePresident ( string name ) : base( name ) {}

            
          // Methods
            override public void ProcessRequest( PurchaseRequest request )
            
          {
              
          if( request.Amount < 25000.0 )
                Console.WriteLine( 
          "{0} {1} approved request# {2}",
                  
          this, name, request.Number);
              
          else
                
          if( successor != null )
                successor.ProcessRequest( request );
            }

          }


          // "ConcreteHandler"
          class President : Approver
          {
            
          // Constructors
            public President ( string name ) : base( name ) {}
            
          // Methods
            override public void ProcessRequest( PurchaseRequest request )
            
          {
              
          if( request.Amount < 100000.0 )
                Console.WriteLine( 
          "{0} {1} approved request# {2}",
                  
          this, name, request.Number);
              
          else
                Console.WriteLine( 
          "Request# {0} requires " +
                  
          "an executive meeting!", request.Number );
            }

          }


          // Request details
          class PurchaseRequest
          {
            
          // Member Fields
            private int number;
            
          private double amount;
            
          private string purpose;

            
          // Constructors
            public PurchaseRequest( int number,  
              
          double amount, string purpose )
            
          {
              
          this.number = number;
              
          this.amount = amount;
              
          this.purpose = purpose;
            }


            
          // Properties
            public double Amount
            
          {
              
          getreturn amount; }
              
          set{ amount = value; }
            }


            
          public string Purpose
            
          {
              
          getreturn purpose; }
              
          set{ purpose = value; }
            }


            
          public int Number
            
          {
              
          getreturn number; }
              
          set{ number = value; }
            }

          }


          /// <summary>
          ///  ChainApp Application
          /// </summary>

          public class ChainApp
          {
            
          public static void Main( string[] args )
            
          {
              
          // Setup Chain of Responsibility
              Director Larry = new Director( "Larry" );
              VicePresident Sam 
          = new VicePresident( "Sam" );
              President Tammy 
          = new President( "Tammy" );
              Larry.SetSuccessor( Sam );
              Sam.SetSuccessor( Tammy );

              
          // Generate and process different requests
              PurchaseRequest rs = new PurchaseRequest( 2034350.00"Supplies" );
              Larry.ProcessRequest( rs );

              PurchaseRequest rx 
          = new PurchaseRequest( 203532590.10"Project X" );
              Larry.ProcessRequest( rx );

              PurchaseRequest ry 
          = new PurchaseRequest( 2036122100.00"Project Y" );
              Larry.ProcessRequest( ry );
            }

          }

           

           

          六、 責任鏈模式的實現

          責任鏈模式并不創建責任鏈。責任鏈的創建必須由系統的其它部分創建出來。

          責任鏈模式降低了請求的發送端和接收端之間的耦合,使多個對象都有機會處理這個請求。一個鏈可以是一條線,一個樹,也可以是一個環。如下圖所示,責任鏈是一個樹結構的一部分。

           


          posted on 2011-11-08 20:53 風清揚 閱讀(279) 評論(0)  編輯  收藏 所屬分類: 設計模式


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


          網站導航:
           
          主站蜘蛛池模板: 自贡市| 台江县| 柳河县| 永嘉县| 肥西县| 敦化市| 行唐县| 博罗县| 彰化县| 寿宁县| 岗巴县| 唐海县| 景德镇市| 尖扎县| 阿尔山市| 龙州县| 龙陵县| 湟中县| 左贡县| 丰镇市| 哈巴河县| 中西区| 鄂州市| 江山市| 怀柔区| 佛教| 全州县| 东阿县| 嘉善县| 云林县| 文登市| 柳林县| 汝州市| 宁武县| 九寨沟县| 大石桥市| 兴宁市| 新津县| 丹凤县| 西藏| 新巴尔虎左旗|