2016-07-29 54 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