Design Patterns(十四):Chain of Responsibility--VB代码

本文介绍了职责链模式的基本概念,包括其动机、意图及结构图。通过示例代码展示了如何使用职责链模式处理请求,使请求发送者与接收者解耦。适用于希望了解职责链模式应用场景与实现方式的读者。

结构图

 

 

角色

  • 抽象处理者(Subject)角色:定义出一个处理请求的接口。 根据需要可以定义出一个设定和返回对下家引用的方法。这个角色通常由一个抽象类或接口实现。
  • 代理主题(Proxy)角色:处理可以处理的请求,将不能处理的请求传递给下家。  

动机

在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。

意图

  
为使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

示意性代码

示意性代码
    'Chain of Responsibility pattern -- Structural example
    Public Class MainApp
        
'MainApp test application
        Public Shared Sub Main()

            
'Setup Chain of Responsibility 
            Dim h1 As Handler = New ConcreteHandler1
            
Dim h2 As Handler = New ConcreteHandler2
            
Dim h3 As Handler = New ConcreteHandler3
            h1.SetSuccessor(h2)
            h2.SetSuccessor(h3)

            
'Generate and process request
            Dim requests() As Integer = {2514221832720}

            
For Each request As Integer In requests
                h1.HandleRequest(request)
            
Next

            
'Wait for user 
            Console.ReadLine()
        
End Sub

    
End Class

    
'"Handler"
    Public MustInherit Class Handler
        
Protected successor As Handler
        
Public Sub SetSuccessor(ByVal successor As Handler)
            
Me.successor = successor
        
End Sub

        
Public MustOverride Sub HandleRequest(ByVal request As Integer)
    
End Class

    
'"ConcreteHandler"
    Public Class ConcreteHandler1
        
Inherits Handler
        
Public Overrides Sub HandleRequest(ByVal request As Integer)
            
If request > 0 And request < 10 Then
                Console.WriteLine(
"{0} handled request {1}"Me.GetType().Name, request)
            
ElseIf successor IsNot Nothing Then
                successor.HandleRequest(request)
            
End If
        
End Sub
    
End Class

    
'"ConcreteHandler"
    Public Class ConcreteHandler2
        
Inherits Handler

        
Public Overrides Sub HandleRequest(ByVal request As Integer)
            
If request > 10 And request < 20 Then
                Console.WriteLine(
"{0} handled request {1}"Me.GetType().Name, request)
            
ElseIf successor IsNot Nothing Then
                successor.HandleRequest(request)
            
End If
        
End Sub
    
End Class

    
'"ConcreteHandler"
    Public Class ConcreteHandler3
        
Inherits Handler
        
Public Overrides Sub HandleRequest(ByVal request As Integer)
            
If request > 20 And request < 30 Then
                Console.WriteLine(
"{0} handled request {1}"Me.GetType().Name, request)
            
ElseIf successor IsNot Nothing Then
                successor.HandleRequest(request)
            
End If
        
End Sub
    
End Class

一个实例

 下面的责任链代码演示了不同职务的人根据所设定的权限对一个购买请求作出决策或将其交给更高的决策者。

实例代码
'MainApp test application
Public Class MainApp
    
Private Shared Sub Main()
        
'Setup Chain of Responsibility
        Dim Larry As New Director()
        
Dim Sam As New VicePresident()
        
Dim Tammy As New President()
        Larry.SetSuccessor(Sam)
        Sam.SetSuccessor(Tammy)

        
'Generate and process purchase requests
        Dim p As New Purchase(2034350"Supplies")
        Larry.ProcessRequest(p)

        p 
= New Purchase(203532590.1"Project X")
        Larry.ProcessRequest(p)

        p 
= New Purchase(2036122100"Project Y")
        Larry.ProcessRequest(p)

        
' Wait for user
        Console.Read()
    
End Sub
End Class

' "Handler"
Public MustInherit Class Approver
    
Protected successor As Approver

    
Public Sub SetSuccessor(ByVal successor As Approver)
        
Me.successor = successor
    
End Sub

    
Public MustOverride Sub ProcessRequest(ByVal purchase As Purchase)
End Class

'"ConcreteHandler"
Public Class Director
    
Inherits Approver
    
Public Overloads Overrides Sub ProcessRequest(ByVal purchase As Purchase)
        
If purchase.Amount < 10000 Then
            Console.WriteLine(
"{0} approved request# {1}"Me.[GetType]().Name, purchase.Number)
        
ElseIf successor IsNot Nothing Then
            successor.ProcessRequest(purchase)
        
End If
    
End Sub
End Class

'"ConcreteHandler"
Public Class VicePresident
    
Inherits Approver
    
Public Overloads Overrides Sub ProcessRequest(ByVal purchase As Purchase)
        
If purchase.Amount < 25000 Then
            Console.WriteLine(
"{0} approved request# {1}"Me.[GetType]().Name, purchase.Number)
        
ElseIf successor IsNot Nothing Then
            successor.ProcessRequest(purchase)
        
End If
    
End Sub
End Class

'"ConcreteHandler"
Public Class President
    
Inherits Approver
    
Public Overloads Overrides Sub ProcessRequest(ByVal purchase As Purchase)
        
If purchase.Amount < 100000 Then
            Console.WriteLine(
"{0} approved request# {1}"Me.[GetType]().Name, purchase.Number)
        
Else
            Console.WriteLine(
"Request# {0} requires an executive meeting!", purchase.Number)
        
End If
    
End Sub
End Class

'Request details
Public Class Purchase
    
Private m_number As Integer
    
Private m_amount As Double
    
Private m_purpose As String

    
'Constructor
    Public Sub New(ByVal number As IntegerByVal amount As DoubleByVal purpose As String)
        
Me.m_number = number
        
Me.m_amount = amount
        
Me.m_purpose = purpose
    
End Sub

    
'Properties
    Public Property Amount() As Double
        
Get
            
Return m_amount
        
End Get
        
Set(ByVal value As Double)
            m_amount 
= value
        
End Set
    
End Property

    
Public Property Purpose() As String
        
Get
            
Return m_purpose
        
End Get
        
Set(ByVal value As String)
            m_purpose 
= value
        
End Set
    
End Property

    
Public Property Number() As Integer
        
Get
            
Return m_number
        
End Get
        
Set(ByVal value As Integer)
            m_number 
= value
        
End Set
    
End Property
End Class

Chain of Responsibility模式的几个要点:
1、Chain of Responsibility模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接收者只有一个,只有这时候请求发送者与接收者的耦合才有可能出现“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好的应对变化。
2、应用了Chain of Responsibility模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。
3、如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的缺省机制,这也是每一个接受对象的责任,而不是发出请求的对象的责任。

我的理解

封装对象责任,支持责任的变化。

参考资料
《C#设计模式(17)-Chain of Responsibility Pattern》        吕震宇
《C#面向对象设计模式纵横谈系列课程(14)》     李建中老师

设计模式:可复用的面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)是一本经典的计算机科学书籍,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides联合编写。 该书首次系统地介绍了23种常见的设计模式,这些模式是面向对象软件开发的重要指导和实践。设计模式是一种对重复出现的问题的解决方案,通过它们可以提供一种通用、可重用和可扩展的设计方法,用于解决软件系统中的常见问题。 《设计模式:可复用的面向对象软件的基础》描述了每个设计模式的结构、目的、应用场景和实现方式。它通过示例代码和详细解释来帮助读者理解每种模式的用途和优缺点。 这本书的主要贡献之一是将设计模式分为三个类别:创建型、结构型和行为型模式。其中,创建型模式关注如何通过不同的方式创建对象,结构型模式关注如何组合对象以形成新功能,行为型模式关注对象之间的通信和协作方式。通过这种分类方式,读者可以更好地理解和应用设计模式。 《设计模式:可复用的面向对象软件的基础》已成为软件工程师必读的经典之作。它提供了一种设计思维的范式,可以帮助开发人员提高软件的扩展性、可读性和可维护性。无论是初学者还是经验丰富的开发人员,阅读并理解设计模式都对他们的软件设计和开发能力有很大的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值