我已经重新考虑了下面显示的方法之一,我个人认为它具有很强的可读性,但我的一位同事并不喜欢它认为这是太多的方法。我错了,如果不是我怎么能说服了他? 原始方法:
Private Sub SendTextMessage(ByVal sender As Object, ByVal eventArgs As EventArgs)
If String.IsNullOrEmpty(SMSUserControl.TxtPhoneProperty) Then
lblError.Text = Globalization.GetTranslation("PhoneNotSet", "A mobile phone number must be specified")
Exit Sub
End If
Try
If Not String.Equals(UserHelper.CurrentUser.Mobile, SMSUserControl.TxtPhoneProperty) Then
UserHelper.CurrentUser.Mobile = SMSUserControl.TxtPhoneProperty
UserHelper.CurrentUser.Properties.Save()
End If
If IPhoneProfilePresenter Is Nothing Then
IPhoneProfilePresenter = New IPhoneProfilePresenter(Me, CabFileNameManagerFactory.Create(), SMSSenderFactory.Create())
End If
IPhoneProfilePresenter.SendTextMessage(New TextMessageInfo(SMSUserControl.TxtPhoneProperty, GetOCSInstallerLink(), DownloadLink.Text))
Catch ex As Exception
lblError.Text = _
CWebLog.LogAndDisplayError(CurrentSession.IsFullLogging, _
Globalization.GetTranslation("MobilePhoneSave", _
"Failed to save the mobile phone number"), _
ex)
End Try
End Sub
重新计算方法:
Private Sub SendTextMessage(ByVal sender As Object, ByVal eventArgs As EventArgs)
If PhoneNumberIsNotSet() Then
lblError.Text = Globalization.GetTranslation("PhoneNotSet", "A mobile phone number must be specified")
Exit Sub
End If
Try
If User_Input_Mobile_Is_Not_The_Same_As_The_One_Stored_In_The_Database() Then
UpdateMobile()
End If
GetIPhoneProfilePresenter().SendTextMessage(New TextMessageInfo(SMSUserControl.Mobile, GetOCSInstallerLink(), DownloadLink.Text))
Catch ex As Exception
lblError.Text = _
CWebLog.LogAndDisplayError(CurrentSession.IsFullLogging, _
Globalization.GetTranslation("MobilePhoneSave", _
"Failed to save the mobile phone number"), _
ex)
End Try
End Sub
Private Sub UpdateMobile()
UserHelper.CurrentUser.Mobile = SMSUserControl.Mobile
UserHelper.CurrentUser.Properties.Save()
End Sub
Private Function User_Input_Mobile_Is_Not_The_Same_As_The_One_Stored_In_The_Database() As Boolean
Return Not String.Equals(UserHelper.CurrentUser.Mobile, SMSUserControl.Mobile)
End Function
Private Function PhoneNumberIsNotSet() As Boolean
Return String.IsNullOrEmpty(SMSUserControl.Mobile)
End Function
Private Function GetIPhoneProfilePresenter() As IPhoneProfilePresenter
If IPhoneProfilePresenter Is Nothing Then
IPhoneProfilePresenter = New IPhoneProfilePresenter(Me, CabFileNameManagerFactory.Create(), SMSSenderFactory.Create())
End If
Return IPhoneProfilePresenter
End Function
根据反馈重新考虑
Private Sub ValidateAndSaveMobilePhoneAndSendTextMessage(ByVal sender As Object, ByVal eventArgs As EventArgs)
If ValidateMobilePhoneNumber() Then
SaveMobilePhoneNumber()
SendTextMessage()
End If
End Sub
Private Sub SendTextMessage()
If iPhoneProfilePresenter Is Nothing Then
iPhoneProfilePresenter = New iPhoneProfilePresenter(Me, CabFileNameManagerFactory.Create(), SMSSenderFactory.Create())
End If
iPhoneProfilePresenter.SendTextMessage(New TextMessageInfo(SMSUserControl.TxtPhoneProperty, GetOCSInstallerLink(), DownloadLink.Text))
End Sub
Private Sub SaveMobilePhoneNumber()
Try
If Not String.Equals(Globalization.CurrentUser.Mobile, SMSUserControl.TxtPhoneProperty) Then
Globalization.CurrentUser.Mobile = SMSUserControl.TxtPhoneProperty
Globalization.CurrentUser.Properties.Save()
End If
Catch ex As Exception
lblError.Text = _
CWebLog.LogAndDisplayError(CurrentSession.IsFullLogging, _
ContentHelper.GetTranslation("MobilePhoneSave", _
"Failed to save the mobile phone number"), _
ex)
End Try
End Sub
Private Function ValidateMobilePhoneNumber() As Boolean
Dim isValid As Boolean = True
If String.IsNullOrEmpty(SMSUserControl.TxtPhoneProperty) Then
lblError.Text = ContentHelper.GetTranslation("PhoneNotSet", "A mobile phone number must be specified")
isValid = False
End If
Return isValid
End Function
答案 0 :(得分:3)
方法应该“只做一件事”(有关详细信息,请参阅此Coding Horror blog post)。这也称为Single Responsibility Principle。
方法应该简短(ish),易于理解且无副作用。您应该能够描述一个方法在其名称中的作用。例如,如果您的方法为VerifyAddressAndAddToDatabase
,则需要将其拆分为两种方法 - VerifyAddress
和AddToDatabase
。
过去,由于涉及管理费用,因此调用大量方法(或称为程序和函数)被认为是一个坏主意。但是对于现代编译器和更快的处理器,这不是问题。
答案 1 :(得分:2)
您关注的可能是Cyclomatic complexity,即代码可以采用的不同路径的数量。可以使用此度量标准来标识good candidates for being refactored的代码片段。
具有高的每方法圈复杂性表明方法变得过于复杂。
不仅仅是你自己的工作,而且任何一个与之合作的人都会遇到困难。
变得困难稍后的那段代码。更好的做法是保持Cyclomatic复杂度低于或等于2;即你的方法在作出决定时不应该采取超过2条路径。
答案 2 :(得分:1)
摆脱'User_Input ...'功能;将该代码内联。否则,这是可以接受的。
这样的功能名称只是荒谬,恕我直言,因为它可能是你想稍后做的稍微多一些,然后你需要更改名称(以免误导)。另外,恕我直言,这很烦人。
答案 3 :(得分:1)
您已将原始方法减少1 if语句,并在交换中添加了4个方法。我会说这会使代码更复杂。
原文实际上是一种3语句方法。这很短,不需要重构。其中一个重构方法的巨大名称暗示它不是重构的好声明。
我只会在原文中添加更多注释,尤其是整个函数的标题注释。
答案 4 :(得分:1)
问他为什么关心“太多”的方法。一般来说,现代语言中的函数调用不会增加显着的开销。为程序员尝试阅读同事的代码节省时间而不是为处理器节省几个时钟周期通常要经济得多。
就我个人而言,我认为阅读一个函数可以提供对其功能的高级概述(因为它包含对其他信息命名方法的调用),而不是我自己必须计算出意图。 / p>
那就是说,正如其他人所指出的那样,User_Input_Mobile_Is_Not_The_Same_As_The_One_Stored_In_The_Database()
并不是我所见过的最干净的方法名称。
答案 5 :(得分:0)
注意:这不是您问题的直接答案,但我无法将其纳入评论......
什么是班级名称/结构?我倾向于遵循经验法则,方法名称应尽可能在类名的上下文中。
如果您的课程为MobileContact
,那么MobileContact.SaveMobilePhoneNumber()
可能会MobileContact.Save()
或MobileContact.User_Input_Mobile_Is_Not_The_Same_As_The_One_Stored_In_The_Database()
成为MobileContact.IsDirty()
。