职责链模式(Chain of Responsibility)

来源:互联网 发布:e4a获取网络图片 编辑:程序博客网 时间:2024/04/29 22:16

1.    定义

       使多个对象都有机会请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

2.      UML 类图

 

3.      结构代码

// Chain of Responsibility pattern -- Structural example

using System;

 

namespace DoFactory.GangOfFour.Chain.Structural

{

  ///<summary>

  /// MainApp startup class for Structural

  /// Chain of Responsibility Design Pattern.

  ///</summary>

  classMainApp

  {

    ///<summary>

    /// Entry point into console application.

    ///</summary>

    staticvoid Main()

    {

      // 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 = { 2, 5, 14, 22, 18, 3, 27, 20 };

 

      foreach (int requestin requests)

      {

        h1.HandleRequest(request);

      }

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  ///<summary>

  /// The 'Handler' abstract class

  ///</summary>

  abstractclass Handler

  {

    protectedHandler successor;

 

    publicvoid SetSuccessor(Handler successor)

    {

      this.successor = successor;

    }

 

    publicabstract void HandleRequest(int request);

  }

 

  ///<summary>

  /// The 'ConcreteHandler1' class

  ///</summary>

  classConcreteHandler1 : Handler

  {

    publicoverride void HandleRequest(int request)

    {

      if (request >= 0 && request < 10)

      {

        Console.WriteLine("{0} handled request {1}",

          this.GetType().Name, request);

      }

      elseif (successor != null)

      {

        successor.HandleRequest(request);

      }

    }

  }

 

  ///<summary>

  /// The 'ConcreteHandler2' class

  ///</summary>

  classConcreteHandler2 : Handler

  {

    publicoverride void HandleRequest(int request)

    {

      if (request >= 10 && request < 20)

      {

        Console.WriteLine("{0} handled request {1}",

          this.GetType().Name, request);

      }

      elseif (successor != null)

      {

        successor.HandleRequest(request);

      }

    }

  }

 

  ///<summary>

  /// The 'ConcreteHandler3' class

  ///</summary>

  classConcreteHandler3 : Handler

  {

    publicoverride void HandleRequest(int request)

    {

      if (request >= 20 && request < 30)

      {

        Console.WriteLine("{0} handled request {1}",

          this.GetType().Name, request);

      }

      elseif (successor != null)

      {

        successor.HandleRequest(request);

      }

    }

  }

}


Output
ConcreteHandler1 handled request 2
ConcreteHandler1 handled request 5
ConcreteHandler2 handled request 14
ConcreteHandler3 handled request 22
ConcreteHandler2 handled request 18
ConcreteHandler1 handled request 3
ConcreteHandler3 handled request 27
ConcreteHandler3 handled request 20

4.      实例代码

// Chain of Responsibility pattern -- Real World example

using System;

 

namespace DoFactory.GangOfFour.Chain.RealWorld

{

  ///<summary>

  /// MainApp startup class for Real-World

  /// Chain of Responsibility Design Pattern.

  ///</summary>

  classMainApp

  {

    ///<summary>

    /// Entry point into console application.

    ///</summary>

    staticvoid Main()

    {

      // Setup Chain of Responsibility

      Approver larry =new Director();

      Approver sam =new VicePresident();

      Approver tammy =new President();

 

      larry.SetSuccessor(sam);

      sam.SetSuccessor(tammy);

 

      // Generate and process purchase requests

      Purchase p =new Purchase(2034, 350.00,"Assets");

      larry.ProcessRequest(p);

 

      p = newPurchase(2035, 32590.10, "Project X");

      larry.ProcessRequest(p);

 

      p = newPurchase(2036, 122100.00, "Project Y");

      larry.ProcessRequest(p);

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  ///<summary>

  /// The 'Handler' abstract class

  ///</summary>

  abstractclass Approver

  {

    protectedApprover successor;

 

    publicvoid SetSuccessor(Approver successor)

    {

      this.successor = successor;

    }

 

    publicabstract void ProcessRequest(Purchase purchase);

  }

 

  ///<summary>

  /// The 'ConcreteHandler' class

  ///</summary>

  classDirector : Approver

  {

    publicoverride void ProcessRequest(Purchase purchase)

    {

      if (purchase.Amount < 10000.0)

      {

        Console.WriteLine("{0} approved request# {1}",

          this.GetType().Name, purchase.Number);

      }

      elseif (successor != null)

      {

        successor.ProcessRequest(purchase);

      }

    }

  }

 

  ///<summary>

  /// The 'ConcreteHandler' class

  ///</summary>

  classVicePresident : Approver

  {

    publicoverride void ProcessRequest(Purchase purchase)

    {

      if (purchase.Amount < 25000.0)

      {

        Console.WriteLine("{0} approved request# {1}",

          this.GetType().Name, purchase.Number);

      }

      elseif (successor != null)

      {

        successor.ProcessRequest(purchase);

      }

    }

  }

 

  ///<summary>

  /// The 'ConcreteHandler' class

  ///</summary>

  classPresident : Approver

  {

    publicoverride void ProcessRequest(Purchase purchase)

    {

      if (purchase.Amount < 100000.0)

      {

        Console.WriteLine("{0} approved request# {1}",

          this.GetType().Name, purchase.Number);

      }

      else

      {

        Console.WriteLine(

          "Request# {0} requires an executive meeting!",

          purchase.Number);

      }

    }

  }

 

  ///<summary>

  /// Class holding request details

  ///</summary>

  classPurchase

  {

    privateint _number;

    privatedouble _amount;

    privatestring _purpose;

 

    // Constructor

    public Purchase(int number,double amount, string purpose)

    {

      this._number = number;

      this._amount = amount;

      this._purpose = purpose;

    }

 

    // Gets or sets purchase number

    publicint Number

    {

      get {return _number; }

      set { _number =value; }

    }

 

    // Gets or sets purchase amount

    publicdouble Amount

    {

      get {return _amount; }

      set { _amount =value; }

    }

 

    // Gets or sets purchase purpose

    publicstring Purpose

    {

      get {return _purpose; }

      set { _purpose =value; }

    }

  }

}


Output
Director Larry approved request# 2034
President Tammy approved request# 2035
Request# 2036 requires an executive meeting!

该文章来自:http://www.dofactory.com/Patterns/PatternChain.aspx

原创粉丝点击