行爲型模式:Chain Of Responsibility 職責鏈模式

                                                  行爲型模式:Chain Of Responsibility 職責鏈模式

1、請求的發送者與接受者
  1)某些對象請求的接受者可能多種多樣,變化無常......
  2)請求發送者→請求接受者1,請求接受者2,請求接受者3,......
 
2、動機(Motivation)
  1)在軟件構建過程當中,一個請求可能被多個對象處理,可是每一個請求在運行時只能有一個接受者,若是顯式指定,將必不可少地帶來請求發送者與接受者的緊耦合。
  2)如何使請求的發送者不須要指定具體的接受者?讓請求的接受者本身在運行時決定來處理請求,從而使二者解耦。
 
3、意圖(Intent)
      使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞請求,直到有一個對象處理它爲止。
                          ——《設計模式》GoF
 
4、實例:
  1)多種狀況的變化來處理一個對象,通常作法以下:
//請求接受者:抽象父類
public abstract class BaseHandler
{
  public abstract void HandleRequest(Request request);
  public abstract bool CanHandleRequest();
}設計模式

//請求接受者A
public class AHandler : BaseHandler
{
  public override void HandleRequest(Request request)
  {
  }
  public override bool CanHandleRequest()
  {
  }
}ide

//請求接受者B
public class BHandler : BaseHandler
{
  public override void HandleRequest(Request request)
  {
  }
  public override bool CanHandleRequest()
  {
  }
}this

//請求接受者C
public class CHandler : BaseHandler
{
  public override void HandleRequest(Request request)
  {
  }
  public override bool CanHandleRequest()
  {
  }
}設計

//請求的發送者
public class Sender
{
  public void Process()
  {
    Request request = new Request();
   
    List<BaseHandler> list = new List<BaseHandler>();
    list.Add(new AHandler());
    list.Add(new BHandler());
    list.Add(new CHandler());
   
    foreach (BaseHandler handler in list)
    {
      //若是可以處理這個請求,那麼就接受請求
      if (handler.CanHandleRequest())
      {
        handler.HandleRequest(request);
      }
    }
  }
}對象

public class Request
{
}繼承

  2)職責鏈模式作法以下:重構獲得模式
//請求接受者:抽象父類
public abstract class BaseHandler
{
  private BaseHandler next;
 
  //構造器配合使用
  public BaseHandler(BaseHandler next)
  {
    this.next = next;
  }
 
  public BaseHandler Next
  {
    get
    {
      return this.next;
    }
    set
    {
      this.next = value;
    }
  }
 
  public virtual void HandleRequest(Request request)
  {
    if (this.next != null)
    {
      this.next.HandleRequest(request);
    }
  }
 
  protected abstract bool CanHandleRequest(Request request);
}get

//請求接受者A
public class AHandler : BaseHandler
{
  public AHandler(BaseHandler next) : base(next)
  {
  }
 
  public override void HandleRequest(Request request)
  {
    if (this.CanHandleRequest(request))
    {
      //若是能處理本身處理
    }
    else
    {
      //不能處理交給基類
      base.HandleRequset(request);
    }
  }
 
  protected override bool CanHandleRequest(Request request)
  {
    if (.....)
    {
      return ture;
    }
    else
    {
      return false;
    }
  }
}it

//請求接受者B
public class BHandler : BaseHandler
{
  public BHandler(BaseHandler next) : base(next)
  {
  }
 
  public override void HandleRequest(Request request)
  {
    if (this.CanHandleRequest(request))
    {
      //若是能處理本身處理
    }
    else
    {
      //不能處理交給基類
      base.HandleRequset(request);
    }
  }
 
  protected override bool CanHandleRequest(Request request)
  {
    if (.....)
    {
      return ture;
    }
    else
    {
      return false;
    }
  }
}io

//請求接受者C
public class CHandler : BaseHandler
{
  public CHandler(BaseHandler next) : base(next)
  {
  }
 
  public override void HandleRequest(Request request)
  {
    if (this.CanHandleRequest(request))
    {
      //若是能處理本身處理
    }
    else
    {
      //不能處理交給基類
      base.HandleRequset(request);
    }
  }
 
  protected override bool CanHandleRequest(Request request)
  {
    if (.....)
    {
      return ture;
    }
    else
    {
      return false;
    }
  }
}class

//請求的發送者
public class Sender
{
  //把請求交給一個對象就好了,無論誰來處理
  public void Process(BaseHandler handler)
  {
    Request request = new Request();
    hnadler.HandlerRequest(request);
  }
}

//客戶
public class App
{
  public static void Main()
  {
    Sender sender = new Sender();
   
    BaseHandler handler1 = new Ahandler(null);
    BaseHandler handler2 = new Bhandler(handler1);
    BaseHandler handler3 = new Chandler(handler2);
   
    BaseHandler handler4 = new Dhandler(null);
    //運行時動態改變鏈表方向
    handler3.Next = handler4;
    handler4.Next = handler2;
   
    sender.Process(handler3);
    //方向:handler3-->handler4-->handler2-->handler1
   
    //程序擴展直接繼承BaseHandler
    //BaseHandler handler4 = new Dhandler(handler3);
    //sender.Process(handler4);
    //......
  }
}

5、Chain Of Responsibility模式的幾個要點   1)Chain Of Responsibility模式的應用場合在於「一個請求可能有多個接受者,可是最後真正的接受者只有一個」,只有這時候請求發送者與接受者的耦合纔有可能出現「變化脆弱」的症狀,職責鏈的目的就是將兩者解耦,從而更好地應對變化。   2)應用了Chain Of Responsibility模式後,對象的職責分派將更具靈活性。咱們能夠在運行時動態添加/修改請求的處理職責。   3)若是請求傳遞到職責鏈的末尾仍得不處處理,應該有一個合理的缺省機制。這也是每個接受對象的責任,而不是發出請求的對象的責任。

相關文章
相關標籤/搜索