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)
@AMissicoenum
实现看起来不错-这是我需要在底层模型中实现的东西?@whytheq,这取决于enum是否仅用于表示层。如果枚举有助于定义模型,则移动到模型中。例如,我曾经有一个名为“Node”的仅用于表示的枚举,用于确定单击了哪个TreeViewItem。它对模型中的其他方法很有用。我把它重构成模型。现在,经过多次使用,它已成为域模型的一部分。