定 义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合,将这些对象连成一条链,并沿着这条链传递该请求,
直到有对象处理它为止
优 点:将请求和处理分开,请求者可以不知道是谁处理的,处理者不用知道请求的全貌,两者解耦,提高了灵活性,责任链模式减低了请求
的发送端和接收端之间的耦合,使多个对象有机会处理这个请求。一个链可以是一条线,一个树,也可以是一个环。链的拓扑结构可
以是单连通的或多连通的,责任链模式并不指定责任链的拓扑结构。但是责任链模式要求在同一时间里,命令只可以被传给一个下家
(或被处理掉),而不可以传给多于一个下家。
缺 点:性能会收到一定的影响,因为每次都要从头传到尾才行
使用环境:
1.系统已经有一个由处理者对象组成的链。这个链可能由合成模式给出。
2.有多于一个的处理者对象会处理一个请求,而且事先并不知道到底由哪一个处理者对象处理一个请求。这个处理者对象是动态确定
3.系统想发出一个请求给多个处理者对象中的某一个,但是不明确指定是哪一个处理者对象会处理此请求。
4.处理一个请求的处理者对象集合需要动态地指定时。
理 解:在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态的重新组织链和分配责任。
应用案例:
先来看看这个责任链模式的UML图:
再来看看这个图的具体解释:
抽象处理者角色(Handler):定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回下家的引用。
具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于处理者持有下家引用,因此,如果需要,具体处理者可以访问下家。
再来看一个我们实际生活中的例子:员工请假,部门经理可以批3天以下的假期,中心总监可批5天以下的假期,副总裁可批10天以下的假期,CEO可以批20天以下假期,超过20天需要开会决定,首先这个审批时有一个流程的,一个基层员工要请假,首先他并不知道这个原则,首先他得去咨询相关人员这个请假规定,然后根据规定来找相关的人,这样对员工来讲非常的苦闷,如果要请20天,那么还得去找CEO,可是CEO并不认识我,这个假还怎么请呢?那么我们使用责任链模式,让员工不再为请假而烦恼,设计的UML图如下:
- Public MustInherit Class Handle
- Private nextHandle As Handle = Nothing
- Public Shared FATHER_LEVEL_REQUEST As Integer = 1
- Public Shared HUSBAND_LEVEL_REQUEST As Integer = 2
- Public Shared SON_LEVEL_REQUEST As Integer = 3
- Private _level As Integer = 0
- '''
- ''' <param name="_women"></param>
- Public Sub HandleMessage(ByVal _women As IWomen)
- If _women.getType1 = _level Then
- response(_women)
- Else
- If nextHandle Is Nothing Then
- Console.WriteLine("无法做出指示,按不同意处理")
- Else
- nextHandle.HandleMessage(_women)
- End If
- End If
- End Sub
- '''
- ''' <param name="_women"></param>
- Protected MustOverride Sub response(ByVal _women As IWomen)
- '''
- ''' <param name="__level"></param>
- Public Sub New(ByVal __level As Integer)
- _level = __level
- End Sub
- Public Sub SetNext(ByVal _nextHandle As Handle)
- nextHandle = _nextHandle
- End Sub
- End Class ' Handle
- Public Class Father
- Inherits Handle
- '''
- ''' <param name="_women"></param>
- Protected Overrides Sub response(ByVal _women As IWomen)
- Console.WriteLine("女儿向父亲请示")
- Console.WriteLine(_women.getRequest())
- Console.WriteLine("父亲对女儿的答复是:同意")
- End Sub
- Public Sub New()
- MyBase.New(Handle.FATHER_LEVEL_REQUEST)
- End Sub
- End Class ' Father
- Public Class Husband
- Inherits Handle
- '''
- ''' <param name="_women"></param>
- Protected Overrides Sub response(ByVal _women As IWomen)
- Console.WriteLine("妻子向丈夫请示")
- Console.WriteLine(_women.getRequest)
- Console.WriteLine("丈夫的请示是:同意")
- End Sub
- Public Sub new()
- MyBase.New(Handle.HUSBAND_LEVEL_REQUEST)
- End Sub
- End Class ' Husband
- Public Class Son
- Inherits Handle
- '''
- ''' <param name="_women"></param>
- Protected Overrides Sub response(ByVal _women As IWomen)
- Console.WriteLine("母亲向儿子请示")
- Console.WriteLine(_women.getRequest)
- Console.WriteLine("儿子对母亲的回复是:同意")
- End Sub
- Public Sub new()
- MyBase.New(Handle.SON_LEVEL_REQUEST)
- End Sub
- End Class ' Son
- Public MustInherit Class IWomen
- Public MustOverride Function getType1() As Integer
- Public MustOverride Function getRequest() As String
- End Class ' IWomen
- Public Class Women
- Inherits IWomen
- Private type As Integer = 0
- Private request As String = ""
- Public Overrides Function getType1() As Integer
- Return type
- End Function
- Public Overrides Function getRequest() As String
- Return request
- End Function
- '''
- ''' <param name="_type"></param>
- ''' <param name="_request"></param>
- Public Sub new(ByVal _type As Integer, ByVal _request As String)
- type = _type
- request = _request
- End Sub
- End Class ' Women
- Module Client
- Sub Main()
- Dim father As Handle = New Father()
- Dim husband As Handle = New Husband
- Dim son As Handle = New Son
- father.SetNext(husband)
- husband.SetNext(son)
- Dim _nver As IWomen = New Women(1, "我要出去上学")
- Dim _qizi As IWomen = New Women(2, "我要出去逛街")
- Dim _mama As IWomen = New Women(3, "我要出去买菜")
- father.HandleMessage(_nver)
- father.HandleMessage(_qizi)
- father.HandleMessage(_mama)
- Console.Read()
- End Sub
- End Module