什么是职责链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之前的耦合关系。将这个对象连成一条链。并沿着这条链传递该请求,直到有一个对象处理它为止。
职责链模式的重心是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回对应的结果。
通用类图
Handler:抽象处理者。
一是定义一个请求的处理方法handleMessage,唯一对外开放的方法;而是定义一个链的编排方法setNext,设置下一个处理者。三是定义了详细的请求者必须实现的两个方法:定义自己可以处理的级别getHandlerLevel和详细的处理任务。
Client类:对责任模式进行封装,直接返回链中的第一个处理者。详细链的设置不须要高层次模块关系。这样降低模块间的耦合,提高系统的灵活性。
通用代码
abstract class Handler { protected Handler successor; public void SetSuccessor(Handler successor) { this.successor = successor; } public abstract void HandleRequest(int request); } class ConcreteHandler1 : Handler { public override void HandleRequest(int request) { if (request >= 0 && request < 10) { Console.WriteLine("{0} 处理请求 {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } } class ConcreteHandler2 : Handler { public override void HandleRequest(int request) { if (request >= 10 && request < 20) { Console.WriteLine("{0} 处理请求 {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } } class ConcreteHandler3 : Handler { public override void HandleRequest(int request) { if (request >= 20 && request < 30) { Console.WriteLine("{0} 处理请求 {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
牛刀小试
在此以机房收费系统学生下机计算消费金额为例,来实现职责链模式。
我们知道关于学生下机操作中须要依据学生上机时间来计算金额。时间分为三种准备时间、至少上机时间、超过至少上机时间。那么我们就能够把这三个时间段分为三个职责来进行操作。
代码例如以下
Public Class Student '学生消费时间 Private consumeTime As Single '学生消费金额 Private consumeMoney As Single '学生消费时间的属性 Property getConsumeTime As Single Get Return consumeTime End Get Set(value As Single) consumeTime = value End Set End Property '学生消费金额的属性 Property getConsumeMoney As Single Get Return consumeMoney End Get Set(value As Single) consumeMoney = value End Set End Property End Class Public MustInherit Class Level '定义水平变量 Protected superior As Level '设置管理上级 Public Sub SetSuperior(superior As Level) Me.superior = superior End Sub '抽象类。用来处理请求 MustOverride Function RequestApplications(request As Student) As Single End Class '准备时间职责 Public Class PrepareTime Inherits Level Public Overrides Function RequestApplications(request As Student) As Single If request.getConsumeTime < 5 Then '当时间小于5分钟时 request.getConsumeMoney = 0 '在这里就直接处理了 ElseIf Not IsNothing(superior) Then '假设大于5分钟的话。我就没有权限了。让上级处理吧 superior.RequestApplications(request) End If Return request.getConsumeMoney End Function End Class '至少上机时间职责 Public Class AtleastTime Inherits Level Public Overrides Function RequestApplications(request As Student) As Single If request.getConsumeTime < 30 Then '小于30分钟的话,我就直接处理了 request.getConsumeMoney = 2 ElseIf Not IsNothing(superior) Then '不行的话,让上级处理 superior.RequestApplications(request) End If Return request.getConsumeMoney End Function End Class '上机时间职责 Public Class OnlineTime Inherits Level Public Overrides Function RequestApplications(request As Student) As Single If request.getConsumeTime > 30 Then '我是最高权限者,能够处理一切 request.getConsumeMoney = 4 / 60 * request.getConsumeTime End If Return request.getConsumeMoney End Function End Class
上述就是通过把三段时间来匹配三种职责的方式,来计算学生金额,从而避免了过多的if……else分支的推断
小结:
职责链模式的长处是将请求和处理分开。请求这不用知道是谁处理的。处理者不用知道请求的全貌,两者解耦,能够提高系统的灵活性。
注意事项:链中节点数量须要控制,避免出现超长链的情况。