职责链模式:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
职责链模式类图:
举例说明:
假如我想请5天假,一般请假方式:如图一:
首先我向纪委请,纪委不可以批5天的假的话,会拒绝我的审批,我会去向纪老师请假,但是也会被拒绝,最后我会向米老师请假,这样的话就会出现的情况是我与各个纪委老师之间的交互太多,在软件上就是耦合。
职责链模式的请假方式,如图二:
我直接向纪委发申请,然后直接等结果就可以,就减少了我与各个老师之间的交互,我不需要去知道由哪几个老师负责请假这件事情,老师也不必知道我的信息,简化了我们之间的连接,效率更高。
机房上机职责链:
在机房上机的时候,我们需要判断三项内容:
1.该用户是否在上机。2,该用于余额是否足够。3.该用户卡号是否存在。
如果每一项都依次判断的话,则每一项都需要从UI层传到DAL层,然后把结果再次传回来,在重构的过程中意识了这样子很麻烦,并且UI层和内部交互太多,于是就学习了职责链模式,减少客户端与逻辑层的耦合。
UI层代码:
在UI层传入了卡号,调用Facade层判断改卡是否在上机的方法。
Dim selectFacade As New Facade.SelectFacade
Dim cardInfo As New JFEntity.CardInfo
cardInfo.Cardno = Trim(txtCardno.Text)
Dim strResult1 As Boolean
strResult1 = selectFacade.CheckInquireOnline(cardInfo)
If strResult1 = False Then
MsgBox("卡号不存在或者已经上机,或者金额小于最小金额", vbOKOnly)
Facade层代码
定义了三者之间的继任关系,先判断卡号是否存在,如果存在,则把请求传递给金额是否足够,如果金额足够,则把请求传给该卡号是否在上机。
'学生上机
Public Function CheckInquireOnline(ByVal cardInfo As JFEntity.CardInfo) As Boolean
Dim checkExitCard As New JFBLL.checkExitCardBLL '判断卡号是否存在
Dim checkOnMoney As New JFBLL.checkOnMoneyBLL '判断余额
Dim checkOn As New JFBLL.checkOn '判断是否在上机
'定义继任者
checkExitCard.setsuccessor(checkOnMoney)
checkOnMoney.setsuccessor(checkOn)
Return checkExitCard.handlecheck(cardInfo)
End Function
BLL层
定义了一个抽象的Handler函数,设置了继任者,以及抽象的处理请求的方法
Public MustInherit Class CheckOnHanderBLL
Protected successor As CheckOnHanderBLL '实例化一个类
Public Sub setsuccessor(ByVal successor As CheckOnHanderBLL) '设置了继承的类
Me.successor = successor
End Sub
Public MustOverride Function handlecheck(ByVal cardInfo As JFEntity.CardInfo) '处理请求的抽象方法
End Class
判断上机卡号是否存在,如果存在,则把请求转向他的继任者。
'判断上机卡号是否存在
Public Class checkExitCardBLL : Inherits CheckOnHanderBLL
Dim flag As Boolean
Dim table As New DataTable
Public Overrides Function handlecheck(cardInfo As JFEntity.CardInfo) As Object
Dim IcheckExitCard As IDAL.IselectDAL
Dim list As New List(Of JFEntity.CardInfo)
IcheckExitCard = Factory.JFFactory.selectInfo
List = IcheckExitCard.selectCard(cardInfo)
If (list.Count < 0) Then
Return False
Exit Function
Else
'设置继任者,检查金额是否足够
Return successor.handlecheck(cardInfo)
End If
End Function
End Class
判断上机余额是否足够,如果足够,则转向判断改卡是否在上机
这里写代码片Imports Factory
'检查上机余额是否足够
Public Class checkOnMoneyBLL : Inherits CheckOnHanderBLL
Public Overrides Function handlecheck(ByVal cardInfo As JFEntity.CardInfo) As Object
'定义接口
Dim list As New List(Of JFEntity.BasicdataEntity)
Dim IcheckCash As IDAL.IselectDAL
IcheckCash = Factory.JFFactory.selectInfo
list = IcheckCash.checkCash()
'卡里的余额
Dim mylist As New List(Of JFEntity.CardInfo)
Dim Iselectcard As IDAL.IselectDAL
Iselectcard = Factory.JFFactory.selectInfo
mylist = Iselectcard.queryBalance(cardInfo)
If (mylist(0).Cash < list(0).limitCash) Then
Return False
Else
'设置继任者,判断是否在上机
Return successor.handlecheck(cardInfo)
End If
End Function
End Class
上机没有继任者,所以如果不在上机,则完全满足条件,返回true,如果在上机,则返回false.告诉客户:卡号不存在或者已经上机,或者金额小于最小金额。
'判断是否在上机
Public Class checkOn : Inherits CheckOnHanderBLL
Public Overrides Function handlecheck(cardInfo As JFEntity.CardInfo) As Object
Dim IcheckOn As IDAL.IselectDAL
Dim table As New DataTable
IcheckOn = Factory.JFFactory.selectInfo
table = IcheckOn.checkOn(cardInfo)
If table.Rows.Count <= 0 Then '没有在上机
Return True
Exit Function
Else
Return false '在上机
End If
End Function
End Class
总结:
通过职责链模式的使用,我直接把请求传给判断卡号是否存在对象,然后直接等结果就可以,我不需要知道他们内部是怎么判断的,这样客户端就会变得很轻松,从而减少客户端和内部代码的耦合。