码迷,mamicode.com
首页 > 其他好文 > 详细

职责链模式<Chain of Responsibility>

时间:2014-05-16 22:06:31      阅读:468      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   c   java   

使多个物件都有机会处理请求,以避免请求的发送者与接收者之间的耦合关系,将这些物件组合为一个链,并沿着这个链传递该请求,直到有物件处理它为止

<通过将多个处理者之间建立联系,来达到请求与具体的某个处理者的解耦>

  

角色成员:

  抽象处理角色(Handler):定义一个处理请求的接口,如果需要,接口可以定义出一个方法以返回或设置对下家的引用 . 通常可以用抽象类或接口实现

  具体处理者(ConcreteHandler):具体处理者接受到请求后,可以选择将请求处理掉或将请求传给下家

 

实现要点:

  有一个抽象责任角色,避免各责任类型之间发生耦合

  抽象责任角色中定义了后继责任角色,并对外提供一个方法供客户端配置

  各具体责任类型根据待处理对象的状态结合自己的责任范围来判断是否能处理对象,如果不能处理提交给上级责任人处理(也就是纯的责任模式,要么自己处理要么提交给别人)。也可以在进行部分处理后再提交给上级处理(也就是不纯的责任链模式)

  需要在客户端链接各个责任对象,如果链接的不恰当,可能会导致部分对象不能被任何一个责任对象进行处理

 

备注:

  纯的责任模式:规定一个具体处理者角色只能对请求作出两种动作:自己处理;传给下家。不能出现处理了一部分,把剩下的传给了下家的情况。而且请求在责任链中必须被处理,而不能出现无果而终的结局。

 

UML图

bubuko.com,布布扣

 

 

 C#代码

bubuko.com,布布扣
bubuko.com,布布扣
 1     /// <summary>
 2     /// 抽象处理者
 3     /// </summary>
 4     public abstract class Handle
 5     {
 6         //定义下一个处理者接口
 7         protected Handle _successor ;
 8 
 9         public void SetSuccessor (Handle successor)
10         {
11             this._successor = successor;
12         }
13 
14         //定义信息处理接口
15         public abstract void HandleRequest (int request);
16 
17     }
18 
19     #region 具体处理者<ConcreteHandler>
20     public class ConcreteHandlerOne : Handle
21     {
22         public override void HandleRequest (int request)
23         {
24             if ( request % 3 == 0 )
25             {
26                 Console.WriteLine ("ConcreteHandlerOne");
27             }
28             else  //不能处理时提交给转移处理
29             {
30                 _successor.HandleRequest (request);
31             }
32            
33         } 
34     }
35 
36     public class ConcreteHandlerTwo : Handle
37     {
38         public override void HandleRequest (int request)
39         {
40             if ( request % 3 == 1 )
41             {
42                 Console.WriteLine ("ConcreteHandlerTwo");
43             }
44             else //不能处理时提交给转移处理
45             {
46                 _successor.HandleRequest (request);
47             }
48             
49         }
50     }
51 
52     public class ConcreteHandlerThree : Handle
53     {
54         public override void HandleRequest (int request)
55         {
56             if ( request % 3 == 2 )
57             {
58                 Console.WriteLine ("ConcreteHandlerThree");
59             }
60             else //不能处理时提交给转移处理
61             {
62                 _successor.HandleRequest (request);
63             }
64         }
65     }
66     #endregion
67 
68 class Program
69     {
70         static void Main (string[] args)
71         {
72 
73             Handle h1 = new ConcreteHandlerOne ();
74             Handle h2 = new ConcreteHandlerTwo ();
75             Handle h3 = new ConcreteHandlerThree ();
76 
77             //设置责任链
78             h1.SetSuccessor (h2);
79             h2.SetSuccessor (h3);
80 
81             int[] requests = new int[] { 2, 4, 5, 6, 7, 44, 67, 23 };
82             foreach ( int request in requests )
83             {
84                 //责任处理
85                 h1.HandleRequest (request);
86             }
87 
88             Console.ReadKey ();
89         }
90     }
View Code
bubuko.com,布布扣


使用  
  从代码角度来说:  如果一个逻辑的处理由不同责任对象完成,客户端希望能自定义这个处理流程并且不希望直接和多个责任对象发生耦合的时候可以考虑责任链模式。

  从应用角度来说:  如果对一个事情的处理存在一个流程,需要经历不同的责任点进行处理,并且这个流程比较复杂或只希望对外公开一个流程的入口点的话可以考虑责任链模式。

 

实例  

  关于办公室发票报销的职责链处理模式  

  办公室的发票,根据它们的金额大小分别由科长,处长,局长逐级负责审阅报批,职责链处理流程从科长到处长再到局长

  

  UML

bubuko.com,布布扣

  

  C#代码

  

bubuko.com,布布扣
bubuko.com,布布扣
  1     public class Receipt
  2     {
  3         public double Amount
  4         {
  5             get;
  6             set;
  7         }
  8 
  9         public string Purpose
 10         {
 11             get;
 12             set;
 13         }
 14 
 15         public Receipt (double amount, string purpose)
 16         {
 17             this.Amount = amount;
 18             this.Purpose = purpose;
 19         }
 20     }
 21 
 22     public abstract class ApproveHandler
 23     {
 24         public string HeadShip
 25         {
 26             get;
 27             set;
 28         }
 29 
 30         protected ApproveHandler _successor;
 31 
 32         public ApproveHandler (string headship)
 33         {
 34             HeadShip = headship;
 35         }
 36 
 37         public void SetSuccessor (ApproveHandler successor)
 38         {
 39             this._successor = successor;
 40         }
 41 
 42         public abstract void HandleRequest (Receipt request);
 43  
 44     }
 45 
 46     #region 具体的处理
 47     public class KeZhangHandle : ApproveHandler
 48     {
 49         public override void HandleRequest (Receipt request)
 50         {
 51             if ( request.Amount <= 1000 )
 52             {
 53                 Console.WriteLine ("{2}大筆一揮,同意了你{0}元{1}的請求", request.Amount, request.Purpose,base.HeadShip);
 54             }
 55             else
 56             {
 57                 _successor.HandleRequest (request);
 58             }
 59         }
 60         public KeZhangHandle (string headship)
 61             : base (headship)
 62         {
 63         }
 64     }
 65 
 66     public class ChuZhangHandle : ApproveHandler
 67     {
 68         public override void HandleRequest (Receipt request)
 69         {
 70             if ( request.Amount <= 10000 )
 71             {
 72                 Console.WriteLine ("{2}不想批,但最後還是同意批了你{0}元{1}的請求", request.Amount, request.Purpose,base.HeadShip);
 73             }
 74             else
 75             {
 76                 _successor.HandleRequest (request);
 77             }
 78         }
 79         public ChuZhangHandle (string headship) 
 80             : base (headship)
 81         {
 82         }
 83     }
 84 
 85     public class JuZhangHandle : ApproveHandler
 86     {
 87         public JuZhangHandle (string headship)
 88             : base (headship)
 89         {
 90         }
 91 
 92         public override void HandleRequest (Receipt request)
 93         {
 94             if ( request.Amount <= 100000 )
 95             {
 96                 Console.WriteLine ("{2}考慮了一下,然後同意了你的{0}元{1}請求", request.Amount, request.Purpose,base.HeadShip);
 97             }
 98             else
 99             {
100                 _successor.HandleRequest (request);
101             }
102         }
103     }
104 
105     public class RefuseHaedler : ApproveHandler
106     {
107         public RefuseHaedler (string headship)
108             : base (headship)
109         {
110         }
111         public override void HandleRequest (Receipt request)
112         {
113             Console.WriteLine ("真的太多了,報不了啦,你自己想辦法吧");
114         }
115     }
116 
117     #endregion
118 
119 
120     class Program
121     {
122         static void Main (string[] args)
123         {
124 
125             Console.WriteLine("-------办公室报销责任链----------");
126 
127 
128             ApproveHandler kz = new KeZhangHandle ("科長");
129             ApproveHandler cz = new ChuZhangHandle ("處長");
130             ApproveHandler jz = new JuZhangHandle ("局長");
131             ApproveHandler refu=new RefuseHaedler("拒絕服務");
132 
133             Receipt[] receipts = new Receipt[]{
134                 new Receipt(1000,"Play"),
135                 new Receipt(10000,"no use"),
136                 new Receipt(100000,"fad"),
137                 new Receipt(100000000,"fa")};
138 
139             //設置責任鏈
140             kz.SetSuccessor (cz);
141             cz.SetSuccessor (jz);
142             jz.SetSuccessor (refu);
143 
144 
145             foreach ( Receipt receipt in receipts )
146             {
147                 kz.HandleRequest (receipt);
148             }
149 
150 
151             Console.ReadKey ();
152         }
153     }
View Code
bubuko.com,布布扣

 

 

职责链模式<Chain of Responsibility>,布布扣,bubuko.com

职责链模式<Chain of Responsibility>

标签:style   blog   class   code   c   java   

原文地址:http://www.cnblogs.com/hjqc/p/3725111.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!