Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 将重复代码移出事件处理程序时的设计模式_Vb.net_Design Patterns - Fatal编程技术网

Vb.net 将重复代码移出事件处理程序时的设计模式

Vb.net 将重复代码移出事件处理程序时的设计模式,vb.net,design-patterns,Vb.net,Design Patterns,我有这个密码: Private Sub carButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles carButton.Click fTrafficSurveyA.incrementCount("Car") Call updateView() End Sub Private Sub bicycleButton_Click(ByVal sender As System.Obj

我有这个密码:

Private Sub carButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles carButton.Click
    fTrafficSurveyA.incrementCount("Car")
    Call updateView()
End Sub
Private Sub bicycleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bicycleButton.Click
    fTrafficSurveyA.incrementCount("Bicycle")
    Call updateView()
End Sub
Private Sub lorryButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lorryButton.Click
    fTrafficSurveyA.incrementCount("Lorry")
    Call updateView()
End Sub
我已将其更改为以下内容:

Private Sub carButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles carButton.Click
    ButtonClickCode(CType(sender, Button))
End Sub
Private Sub bicycleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bicycleButton.Click
    ButtonClickCode(CType(sender, Button))
End Sub
Private Sub lorryButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lorryButton.Click
    ButtonClickCode(CType(sender, Button))
End Sub

Private Sub ButtonClickCode(ByVal mySender As Button)

    Dim incrementVehicle As String
    Select Case mySender.Name
        Case "carButton"
            incrementVehicle = "Car"
        Case "bicycleButton"
            incrementVehicle = "Bicycle"
        Case "lorryButton"
            incrementVehicle = "Lorry"
        Case Else
            incrementVehicle = ""
    End Select

    fTrafficSurveyA.incrementCount(incrementVehicle)
    Call updateView()

End Sub
新代码有更多的代码行。
新版本是更好的实践,还是我应该遵循第三种模式


编辑

使用Guffa的回答和其他评论,我更改了基础的
TrafficSurveyA
模型,以包含枚举类型,并更改了它的函数
incrementCount
,就像这样……枚举类型的位置正确吗

Enum vehicleType
    Car
    Lorry
    Bicycle
End Enum

Public Sub incrementCount(ByVal vehicle As vehicleType)
    ' Preconditions: none
    ' Postconditions: If vehicle is "Car", "Bicycle" or "Lorry" then 1 is added
    ' to the corresponding count. Otherwise nothing is done.

    Select Case vehicle
        Case vehicleType.Car : fCars = fCars + 1
        Case vehicleType.Bicycle : fBicycles = fBicycles + 1
        Case vehicleType.Lorry : fLorries = fLorries + 1
        Case Else 'do nothing
    End Select
End Sub
接口代码的结果如下所示:

Private Sub carButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles carButton.Click
    ButtonClickCode(TrafficSurveyA.vehicleType.Car)
End Sub
Private Sub bicycleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bicycleButton.Click
    ButtonClickCode(TrafficSurveyA.vehicleType.Bicycle)
End Sub
Private Sub lorryButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lorryButton.Click
    ButtonClickCode(TrafficSurveyA.vehicleType.Lorry)
End Sub
Private Sub ButtonClickCode(ByVal incrementVehicle As TrafficSurveyA.vehicleType)

    fTrafficSurveyA.incrementCount(incrementVehicle)
    Call updateView()

End Sub

由于事件处理程序中的代码是相同的,因此所有事件只能有一个事件处理程序:

Private Sub vehicleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles carButton.Click, bicycleButton.Click, lorryButton.Click
  Dim mySender As Button = CType(sender, Button)

  Dim incrementVehicle As String
  Select Case mySender.Name
    Case "carButton"
      incrementVehicle = "Car"
    Case "bicycleButton"
      incrementVehicle = "Bicycle"
    Case "lorryButton"
      incrementVehicle = "Lorry"
    Case Else
      incrementVehicle = ""
  End Select

  fTrafficSurveyA.incrementCount(incrementVehicle)
  Call updateView()

End Sub
另一种选择是保留单独的事件处理程序,并使用每个事件处理程序都可以向公共方法发送正确的文本这一事实,因此不需要检查控件名称来确定文本:

Private Sub carButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles carButton.Click
  ButtonClickCode("Car")
End Sub

Private Sub bicycleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bicycleButton.Click
  ButtonClickCode("Bicycle")
End Sub

Private Sub lorryButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lorryButton.Click
  ButtonClickCode("Lorry")
End Sub

Private Sub ButtonClickCode(ByVal incrementVehicle As String)
  fTrafficSurveyA.incrementCount(incrementVehicle)
  Call updateView()
End Sub

建议:不要使用Name属性。如果有人出现并更改了控件的名称,则代码将中断。更好地使用mySender的是“{carButton | bicycleButton | lorryButton}”。然后,当在Visual Studio中更改名称时,将更改代码以反映新名称。避免在可以使用枚举的位置传递字符串。这种方式使用的字符串不是类型安全的,除非用户在进行更改时小心导致错误。我推荐使用枚举实现的替代方法。例如,
ButtonClickCode(VehicleType.Car)
@AMissico
enum
实现看起来不错-这是我需要在底层模型中实现的东西?@whytheq,这取决于enum是否仅用于表示层。如果枚举有助于定义模型,则移动到模型中。例如,我曾经有一个名为“Node”的仅用于表示的枚举,用于确定单击了哪个TreeViewItem。它对模型中的其他方法很有用。我把它重构成模型。现在,经过多次使用,它已成为域模型的一部分。