2016-07-29 23 views
0

没有可以由A类避免了参数类长的case语句

里面的A级执行的任务的类层次结构还有很长的case语句检查任务类,并调用相应的处理程序方法。

Class Task 
End Class 

Class TaskX 
Inherits Task 
End Class 

Class TaskY 
Inherits Task 
End Class 

... 


Class A 
    Public Sub PerformTask(Task As Task) 
     Select Case Task.GetType 
      Case GetType(TaskX) 
       PerformTaskX(CType(Task, TaskX)) 
      Case GetType(TaskY) 
       PerformTaskY(CType(Task, TaskY)) 
     End Select 
    End Sub 


    Private Sub PerformTaskX(Task As TaskX) 
    End Sub 

    Private Sub PerformTaskY(Task As TaskY) 
    End Sub 

    ... 
End Class 

任务有它们各自的参数,验证逻辑等。这个例子被简化了。

我想避免这种情况,我正在寻找替代解决方案。

的总体思路是类映射类型的处理程序(类),这可以在某种程度上像这样工作:

Delegate Sub Handler(Task As Task) 

Private TypeToHandlerDict As New Dictionary(Of System.Type, Handler) From { _ 
      {GetType(TaskX), AddressOf PerformTaskX}, _ 
      {GetType(TaskY), AddressOf PerformTaskY} _ 
     } 

,这样我可以用更优雅的更换PerformTask方法内容:

Public Sub PerformTask(Task As Task) 
    Dim handler As Handler = Nothing 
    If Not TypeToHandlerDict.TryGetValue(Task.GetType, handler) Then Exit Sub 
    handler(Task) 
End Sub 

但它不起作用。

委托绑定到Task类型,但处理程序方法接受任务子类参数。我正在使用Option Strict。 我可以重写所有处理程序方法来接受任务对象并执行显式强制转换,但这同样不雅观。

有什么建议吗? 谢谢!

更新:这是解决方案感谢@Sehnsucht的答案。

Class Task 
    Public MustOverride Sub Perform(a As A) 
End Class 

Class TaskX 
Inherits Task 
    Public Overrides Sub Perform(a As A) 
     a.DoThis() 
    End Sub 
End Class 

Class TaskY 
Inherits Task 
    Public Overrides Sub Perform(a As A) 
     a.DoThat() 
    End Sub 
End Class 

... 


Class A 
    Public Sub PerformTask(Task As Task) 
     Task.Perform(Me) 
    End Sub 


    Public Sub DoThis() 
    End Sub 

    Public Sub DoThat() 
    End Sub 

    ... 
End Class 
+0

你可以添加一个'Perform'或'Execute'方法任务类,让他们做的工作?如果需要,也许使用'ITask'接口。 – Plutonix

+0

你可以把PerformTask作为一个必须覆盖功能内的任务和他们每个TaskX实现自己的版本?这样,你只需调用task.PerformTask() –

+1

除了你已经提出了8个问题并获得了10个答案,但没有标记任何一个被接受。接受最好的答案,如果有的话,并upvoting帮助其他用户找到很好的答案。 [参观]以非常简短的形式解释这一点和其他内容。 – Plutonix

回答

0

所有PerformTask...具有相同的签名而这由委托Handler您在您的文章显示执行。
因此,您应该在Task类中使用默认实现(或者如果Task类为MustInherit,则将该方法标记为MustOverride),并由继承者根据其特定情况执行该作业将覆盖该方法。

Class Task 
    Public Overridable Sub Perform() 
     ' implementation specific to Task ("default" case) 
    End Sub 
End Class 

Class TaskX 
    Inherits Task 

    Public Overrides Sub Perform() 
     ' implementation specific to TaskX 
     ' you can call the parent implementation if needed with 
     MyBase.Perform() 
    End Sub 
End Class 

'Usage 
Class A 
    Public Sub PerformTask(task As Task) 
     task.Perform() ' will call the "right one" according to it's runtime type 
    End Sub 
End Class 
+0

执行任务涉及到A类内部的业务逻辑(“_how_ should it done”),而任务只知道“应该完成什么”。 在任务中创建带有类A参数的Execute方法,并让任务调用类A的公开业务逻辑是可能的,但我不喜欢这种解决方案。 – Manolis

+0

@Manolis从未声明任务类只包含关于* what *而不是* how *的数据。几乎相反,对于我来说,当你说每个任务都有单独的参数,验证逻辑......它暗示我每个人都知道它会如何表现。有了额外的信息,您的评论,除了最初的帖子,我可能会有不同的答案:-) – Sehnsucht

+0

显然,唯一的解决方案的工作,确实是利用多态性,并使每个任务后裔能够执行自己。 为了在我们的系统中实现这一点,我需要公开A类的一些逻辑并更改Task的多态执行方法,以便接受A作为参数,以便它可以调用它想要的逻辑。 谢谢! – Manolis