文章出處

索引

意圖

使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。

將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它位置。

Avoid 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.

結構

一個典型的對象結構可能如下圖所示:

參與者

Handler

  • 定義一個處理請求的接口。
  • 實現后繼鏈

ConcreteHandler

  • 處理它所負責的請求。
  • 可訪問它的后繼者。
  • 如果可處理該請求,就處理;否則將該請求轉發給它的后繼者。

Client

  • 向鏈上的具體處理者對象提交請求。

適用性

在以下情況下可以使用 Chain of Responsibility 模式:

  • 有多個對象可以處理一個請求,哪個對象處理該請求運行時自動確定。
  • 你想在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
  • 可處理一個請求的對象集合應被動態指定。

效果

  • 降低耦合度。對象無需知道哪個一個對象處理其請求,僅需知道對象被處理。
  • 增強了給對象指派職責的靈活性。可以運行時對該鏈進行動態增加或修改。

相關模式

  • Chain of Resposibility 常與 Composite 一起使用。一個構件的父構件可作為它的后繼。

實現

實現方式(一):實現后繼者鏈。

  1 namespace ChainOfResponsibilityPattern.Implementation1
  2 {
  3   public enum RequestCategory
  4   {
  5     Category1,
  6     Category2,
  7   }
  8 
  9   public abstract class Request
 10   {
 11     public abstract RequestCategory Category { get; }
 12     public bool IsHandled { get; set; }
 13   }
 14 
 15   public class ConcreteRequest1 : Request
 16   {
 17     public override RequestCategory Category
 18     {
 19       get { return RequestCategory.Category1; }
 20     }
 21   }
 22 
 23   public class ConcreteRequest2 : Request
 24   {
 25     public override RequestCategory Category
 26     {
 27       get { return RequestCategory.Category2; }
 28     }
 29   }
 30 
 31   public abstract class Handler
 32   {
 33     private Handler _successor;
 34 
 35     public Handler()
 36     {
 37     }
 38 
 39     public Handler(Handler successor)
 40     {
 41       _successor = successor;
 42     }
 43 
 44     public void Handle(Request request)
 45     {
 46       OnHandle(request);
 47 
 48       if (!request.IsHandled)
 49       {
 50         if (_successor != null)
 51         {
 52           // pass request to successor
 53           _successor.Handle(request);
 54         }
 55       }
 56     }
 57 
 58     protected abstract void OnHandle(Request request);
 59   }
 60 
 61   public class ConcreteHandler1 : Handler
 62   {
 63     public ConcreteHandler1()
 64     {
 65     }
 66 
 67     public ConcreteHandler1(Handler successor)
 68       : base(successor)
 69     {
 70     }
 71 
 72     protected override void OnHandle(Request request)
 73     {
 74       if (request.Category == RequestCategory.Category1)
 75       {
 76         // handle the request which category is Category1
 77         request.IsHandled = true;
 78       }
 79     }
 80   }
 81 
 82   public class ConcreteHandler2 : Handler
 83   {
 84     public ConcreteHandler2()
 85     {
 86     }
 87 
 88     public ConcreteHandler2(Handler successor)
 89       : base(successor)
 90     {
 91     }
 92 
 93     protected override void OnHandle(Request request)
 94     {
 95       if (request.Category == RequestCategory.Category2)
 96       {
 97         // handle the request which category is Category2
 98         request.IsHandled = true;
 99       }
100     }
101   }
102 
103   public class Client
104   {
105     public void TestCase1()
106     {
107       Request request1 = new ConcreteRequest1();
108       Request request2 = new ConcreteRequest2();
109 
110       Handler handler2 = new ConcreteHandler2();
111       Handler handler1 = new ConcreteHandler1(handler2);
112 
113       handler1.Handle(request1);
114       handler1.Handle(request2);
115     }
116   }
117 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()