我在内部应用程序上使用.Net Reflector来尝试理解之前的Dev正在做什么以及学习.我从来没有关于如何开发应用程序的实际指导,所以我从可能的地方采取(Hooray Stack Overflow).话虽如此,我发现了让我困惑的事情.一个名为WinConstant的类库,包含以下代码.
这是我的实际问题:
这可能有什么用?
将一堆常量存储在类库中有什么价值?
这被认为是"最佳实践"吗?
思想和指导赞赏!
Public Class clsConstant
Public Const cAccess As String = "Access"
Public Const cAddress As String = "Address"
Public Const cCancel As String = "Cancel"
Public Const cCity As String = "City"
Public Const cClear As String = "Clear"
Public Const cClickOnMessage As String = "Click on any row in top pane to see the detail fields in the bottom pane."
Public Const cClientID As String = "ClientID"
Public Const cColon As String = ": "
Public Const cComma As String = ","
Public Const cContactID As String = "ContactID"
Public Const cCounty As String = "County"
Public Const cDash As String = "-"
Public Const cDelete As String = "Delete"
Public Const cDepartment As String = "Department"
Public Const cError As String = "Error"
Public Const cExec As String = "Exec"
Public Const cFalse As String = "False"
Public Const cFavorite As String = "Favorite"
Public Const cFederal As String = "Federal"
Public Const cFriday As String = "Friday"
Public Const cfrmMain As String = "frmMain"
Public Const cfrmModuleLogin As String = "frmModuleLogin"
Public Const cfrmModuleSplash As String = "frmModuleSplash"
Public Const cHelp As String = "Help"
Public Const cHint As String = "Hint"
Public Const cImagePath As String = "../../image"
Public Const cIn As String = "In"
Public Const cInformation As String = "Information"
Public Const cInitialScreenID As String = "InitialScreenID"
Public Const cInsert As String = "Insert"
Public Const cJuvenileID As String = "JuvenileID"
Public Const cLetter As String = "Letter"
Public Const cManual As String = "Manual"
Public Const cMasterID As String = "MasterID"
Public Const cModuleID As String = "ModuleID"
Public Const cModuleName As String = "ModuleName"
Public Const cMonday As String = "Monday"
Public Const cName As String = "Name"
Public Const cNegative As String = "Negative"
_
Public Shared ReadOnly cNLowDate As DateTime = New DateTime(&H851055320574000)
_
Public Shared ReadOnly cNullDate As DateTime = New DateTime
Public Const cNullDateString As String = "12:00:00 AM"
Public Const cOfficeIDDefault As String = "01"
Public Const cOne As Integer = 1
Public Const cOut As String = "Out"
Public Const cPopUp As String = "PopUp"
Public Const cPositive As String = "Positive"
Public Const cProcess As String = "Process"
Public Const cProviderID As String = "ProviderID"
Public Const cQuestion As String = "Question"
Public Const cRead As String = "Read"
Public Const cReferralID As String = "ReferralID"
Public Const cReminder As String = "Reminder"
Public Const cReport As String = "Report"
Public Const cReportEngine As String = "ReportEngine"
Public Const cReportEnginePath As String = "ReportEnginePath"
Public Const cReportingServices As String = "ReportingServices"
Public Const cReportServer As String = "ReportServer"
Public Const cReportService As String = "ReportService"
Public Const cReportServiceLocal As String = "ReportServiceLocal"
Public Const cReportServiceServer As String = "ReportServiceServer"
Public Const cSaturday As String = "Saturday"
Public Const cSearch As String = "Search"
Public Const cSelect As String = "Select"
Public Const cSpace As String = " "
Public Const cSQLLoginError As String = "SQL Server login/password invalid"
Public Const cStart As String = "Select a module"
Public Const cState As String = "State"
Public Const cSubjectID As String = "SubjectID"
Public Const cSunday As String = "Sunday"
Public Const cThursday As String = "Thursday"
Public Const cTooltipCancel As String = "Reset form data values back to before all manual changes."
Public Const cTooltipClear As String = "Clears all data entry fields prior to an Insert"
Public Const cTooltipClient As String = "Display a Client popup window."
Public Const cTooltipClose As String = "Close this form"
Public Const cTooltipDelete As String = "Delete the current record being displayed, no undo possible."
Public Const cTooltipExe As String = "Initiate a batch process."
Public Const cTooltipInsert As String = "Insert a brand new record"
Public Const cTooltipSearch As String = "Perform a Search for values entered."
Public Const cTooltipSelect As String = "Perform a Select for values entered."
Public Const cTooltipUpdate As String = "Update an existing record"
Public Const cTrue As String = "True"
Public Const cTuesday As String = "Tuesday"
Public Const cUnderscore As String = "____________________________________________________________"
Public Const cUpdate As String = "Update"
Public Const cWarning As String = "Warning"
Public Const cWeb As String = "Web"
Public Const cWednesday As String = "Wednesday"
Public Const cWorkerID As String = "WorkerID"
Public Const cZero As Integer = 0
Public Shared strLongDate As String() = DateAndTime.Now.ToLongDateString.Split(New Char() { ","c })
Public Shared strModuleMainStatusStripFormID As String = Nothing
End Class
Run Code Online (Sandbox Code Playgroud)
回到用c编码windows应用程序的时代,Windows中有类似的文件#included,其中包含#defines创建常量的长列表.各种c应用程序在自己的文件中模拟了这种方法."阶级"似乎是这种"c-ism"的"音译".面向对象设计的基本原则是将代码和数据混合到相关的功能单元:对象中.正如jfullerton写道:
从编程的角度来看,面向对象涉及程序对象,封装,继承和多态.概念对象在程序代码中建模.封装保持对象的数据和方法,这些数据和方法将数据一起用作对象的一部分.
很明显,这个常数列表不符合OO实践,但是回归过去.
回答你的问题:
当然,如果这是您的应用程序的一部分,您不能只是扔掉它.相反,假设您使用测试驱动开发和重构的当前最佳实践,这可以随着时间的推移重构
将文字与其余代码分开是个好主意.
奇怪的是,这些应该主要是资源而不是常量字符串.然后,如果需要,可以轻松地对其进行本地化,或者在不重新编译整个应用程序的情况下替换/更新.
其中一些甚至不是资源:cUnderscore例如看起来它使用文本来创建视觉效果 - 通常是一个坏主意.
在你的前任的辩护中,我认为这个代码比寻找分散在整个源代码中的相同常量更为可取,因为它会使资源的重构变得更简单一些.
常数是永远不会改变的东西,例如
Public Const NumberOne as Int = 1
Run Code Online (Sandbox Code Playgroud)
所以这是我的第一句话:你总结的一些东西并不是真正的常量。
另一个缺点是使用 const 关键字会创建二进制依赖。这意味着您将不得不重建使用您的 constants.dll 的程序集。你不能只是更换它。这是由 consts 的工作方式引起的:编译器在编译时用值替换名称。
此问题的解决方案是使用 ReadOnly 而不是 Const。
我真的不认为创建这样的库是一个好习惯。无论如何,我不会允许我的团队创建一个...
看起来开发人员有一个编码标准:不要在代码中使用字符串文字,并尽职地分离出每个常量,无论它是否有意义。
例如,代码中可能有某个元素需要数字 1,但他们没有使用 DefaultNumberOfLineItems 或其他描述性常量,而是使用 NumberOne = 1;
最佳实践是保持常量的描述性并接近其使用点。具有某种含义并且彼此相关的相关常量的静态类没有任何问题。
例如,我开发了一个系统,该系统使用唯一键标记属性。这些键聚集在一个静态类中,并在属性上具有描述性名称,实际上键是由自动化系统生成的
public static class AttributeIDs
{
public const string Name = "UniqueGeneratedKeyForNameAttribute";
public const string Description ="UnqiueGeneratedKeyForDescriptionAttribute";
... etc.
}
Run Code Online (Sandbox Code Playgroud)
在实践中,这就像
MyAccess.GetValueForAttribute(AttributeIDs.Name);
Run Code Online (Sandbox Code Playgroud)
它将所有相关的常量放在一起。