标签:style blog class code c java
使多个物件都有机会处理请求,以避免请求的发送者与接收者之间的耦合关系,将这些物件组合为一个链,并沿着这个链传递该请求,直到有物件处理它为止
<通过将多个处理者之间建立联系,来达到请求与具体的某个处理者的解耦>
角色成员:
抽象处理角色(Handler):定义一个处理请求的接口,如果需要,接口可以定义出一个方法以返回或设置对下家的引用 . 通常可以用抽象类或接口实现
具体处理者(ConcreteHandler):具体处理者接受到请求后,可以选择将请求处理掉或将请求传给下家
实现要点:
有一个抽象责任角色,避免各责任类型之间发生耦合
抽象责任角色中定义了后继责任角色,并对外提供一个方法供客户端配置
各具体责任类型根据待处理对象的状态结合自己的责任范围来判断是否能处理对象,如果不能处理提交给上级责任人处理(也就是纯的责任模式,要么自己处理要么提交给别人)。也可以在进行部分处理后再提交给上级处理(也就是不纯的责任链模式)
需要在客户端链接各个责任对象,如果链接的不恰当,可能会导致部分对象不能被任何一个责任对象进行处理
备注:
纯的责任模式:规定一个具体处理者角色只能对请求作出两种动作:自己处理;传给下家。不能出现处理了一部分,把剩下的传给了下家的情况。而且请求在责任链中必须被处理,而不能出现无果而终的结局。
UML图
C#代码
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 }
使用
从代码角度来说: 如果一个逻辑的处理由不同责任对象完成,客户端希望能自定义这个处理流程并且不希望直接和多个责任对象发生耦合的时候可以考虑责任链模式。
从应用角度来说: 如果对一个事情的处理存在一个流程,需要经历不同的责任点进行处理,并且这个流程比较复杂或只希望对外公开一个流程的入口点的话可以考虑责任链模式。
实例
关于办公室发票报销的职责链处理模式
办公室的发票,根据它们的金额大小分别由科长,处长,局长逐级负责审阅报批,职责链处理流程从科长到处长再到局长
UML
C#代码
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 }
职责链模式<Chain of Responsibility>,布布扣,bubuko.com
职责链模式<Chain of Responsibility>
标签:style blog class code c java
原文地址:http://www.cnblogs.com/hjqc/p/3725111.html