设计模式之Chain of Responsibility职责链模式


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

适用性:

  • 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
  • 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可处理一个请求的对象集合应被动态指定。

DefinitionAvoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

participants

    The classes and/or objects participating in this pattern are:

  • Handler   (Approver)
    • defines an interface for handling the requests
    • (optional) implements the successor link
  • ConcreteHandler   (Director, VicePresident, President)
    • handles requests it is responsible for
    • can access its successor
    • if the ConcreteHandler can handle the request, it does so; otherwise it forwards the request to its successor
  • Client   (ChainApp)
    • initiates the request to a ConcreteHandler object on the chain

Chain of Responsibility职责链模式,其实也很简单的。就是说有一些concrete class,其中针对特定的interface or abstract class,针对特殊情况有了特别的实现。然后,在实际情况中遇到特别的对象的话再在这里找一个具体的实现对象来执行。其中多个对象组成一条链,就是所谓的职责链了。

 

Sample code in c#

This structural code demonstrates the Chain of Responsibility pattern in which several linked objects (the Chain) are offered the opportunity to respond to a request or hand it off to the object next in line.

// Chain of Responsibility pattern -- Structural example

 

using System;

namespace DoFactory.GangOfFour.Chain.Structural
{
  // MainApp test application

  class MainApp
  {
    static void 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 request in requests)
      {
        h1.HandleRequest(request);
      }

      // Wait for user
      Console.Read();
    }
  }

  // "Handler"

  abstract class Handler
  {
    protected Handler successor;

    public void SetSuccessor(Handler successor)
    {
      this.successor = successor;
    }

    public abstract void HandleRequest(int request);
  }

  // "ConcreteHandler1"

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

  // "ConcreteHandler2"

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

  // "ConcreteHandler3"

  class ConcreteHandler3 : Handler
  {
    public override void HandleRequest(int request)
    {
      if (request >= 20 && request < 30)
      {
        Console.WriteLine("{0} handled request {1}",
          this.GetType().Name, request);
      }
      else if (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

 

This real-world code demonstrates the Chain of Responsibility pattern in which several linked managers and executives can respond to a purchase request or hand it off to a superior. Each position has can have its own set of rules which orders they can approve.

// Chain of Responsibility pattern -- Real World example

 

using System;

namespace DoFactory.GangOfFour.Chain.RealWorld
{

  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      // Setup Chain of Responsibility
      Director Larry = new Director();
      VicePresident Sam = new VicePresident();
      President Tammy = new President();
      Larry.SetSuccessor(Sam);
      Sam.SetSuccessor(Tammy);

      // Generate and process purchase requests
      Purchase p = new Purchase(2034, 350.00, "Supplies");
      Larry.ProcessRequest(p);

      p = new Purchase(2035, 32590.10, "Project X");
      Larry.ProcessRequest(p);

      p = new Purchase(2036, 122100.00, "Project Y");
      Larry.ProcessRequest(p);

      // Wait for user
      Console.Read();
    }
  }

  // "Handler"

  abstract class Approver
  {
    protected Approver successor;

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

    public abstract void ProcessRequest(Purchase purchase);
  }

  // "ConcreteHandler"

  class Director : Approver
  {
    public override void ProcessRequest(Purchase purchase)
    {
      if (purchase.Amount < 10000.0)
      {
        Console.WriteLine("{0} approved request# {1}",
          this.GetType().Name, purchase.Number);
      }
      else if (successor != null)
      {
        successor.ProcessRequest(purchase);
      }
    }
  }

  // "ConcreteHandler"

  class VicePresident : Approver
  {
    public override void ProcessRequest(Purchase purchase)
    {
      if (purchase.Amount < 25000.0)
      {
        Console.WriteLine("{0} approved request# {1}",
          this.GetType().Name, purchase.Number);
      }
      else if (successor != null)
      {
        successor.ProcessRequest(purchase);
      }
    }
  }

  // "ConcreteHandler"

  class President : Approver
  {
    public override 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);
      }
    }
  }

  // Request details

  class Purchase
  {
    private int number;
    private double amount;
    private string purpose;

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

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

    public string Purpose
    {
      get{ return purpose; }
      set{ purpose = value; }
    }

    public int Number
    {
      get{ return number; }
      set{ number = value; }
    }
  }
}

 

Output

Director Larry approved request# 2034

President Tammy approved request# 2035

Request# 2036 requires an executive meeting!

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值