2009-01-30 4 views
4

Я использовал .Net Reflector на внутреннем приложении, чтобы попытаться понять, что делал предыдущий Дев, а также учиться. У меня никогда не было инструкция о том, как разрабатывать приложения, поэтому я беру оттуда, где могу (переполнение стека Hooray). Сказав это, я нашел кое-что, что меня смутило. Библиотека классов под названием WinConstant, содержащая приведенный ниже код.Библиотека констант - лучшая практика?

Вот мой актуальный вопрос:

  1. Что можно использовать это может быть?

  2. Какое значение имеется при хранении связки констант в классе ?

  3. Считается ли это "Лучшим Практика"?

Мысли и руководство оценили!


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 

ответ

8

В дни кодирования оконных приложений в c были похожие файлы #, включенные в окна, которые состояли из long списков констант #defines, создающих константы. Различные приложения c имитировали этот подход в своих собственных файлах. «Класс» кажется «транслитерацией» этого «c-ism». Фундаментальный принцип объектно-ориентированного проектирования заключается в смешении кода и данных с соответствующими функциональными единицами: объектами. Как jfullerton писал:

С точки зрения программирования, объектно- ориентация включает в себя программу объектов, инкапсуляция, наследование, и полиморфизм. Концептуальные объекты моделируются в программе . Инкапсуляция хранит данные и методы объекта , которые совместно используют данные вместе как часть объекта.

Таким образом, этот постоянный список не соответствует методам ОО, а является возвратом к старым дням.

Чтобы ответить на ваши вопросы:

  1. - Этот класс содержит константы, то есть
  2. - старый разработчик, вероятно, сделал это, потому что это было то, что он привык делать
  3. - Это не текущие лучшие практики.

Естественно, если это часть вашего приложения, вы не можете просто выбросить его. Скорее всего, это то, чтобы реорганизовать в течение долгого времени, если вы используете текущие лучшие практики Test Driven Development и Refactoring

+0

Этот код также напоминает файлы .h. –

+1

Есть еще очень веские причины для использования классов, состоящих из констант. Не все в мире программирования может/будет соответствовать чистым идеалам OO. Для получения дополнительных пояснений см. Некоторые другие ответы. Это не обязательно то, что нужно реорганизовать. –

+1

Этот список хорош, когда вы работаете с большим количеством наборов данных/данных и должны ссылаться на столбцы или таблицы из многих частей приложения. – StingyJack

0

Единственное объяснение, о котором я могу думать, это как-то вроде библиотеки сообщений, но это не относится к 90% записей.

Например, это просто глупо:

Public Const cInsert As String = "Insert" 

Это пахнет очень и очень плохо.

4

Константа является то, что никогда не меняется, например

Public Const NumberOne as Int = 1 

Так что это мое первое замечание: некоторые вещи вы суммировал это на самом деле не Уст.

Другой недостаток заключается в том, что использование ключевого слова const создает двоичный параметр. Это означает, что вам придется перестроить сборку, которая использует ваш файл констант.dll. Вы не можете просто заменить его. Это вызвано тем, как работают consts: компилятор заменяет имя значением во время компиляции.

Решение этой проблемы заключается в использовании ReadOnly вместо Const.

Я действительно не думаю, что это хорошая практика для создания такой библиотеки. Я бы не разрешил моей команде создавать один так или иначе ...

7

Отделив литералов от остальной части кода - это хорошая идея.

Что странно, что в основном это ресурсы, а не постоянные строки. Затем они могут быть легко локализованы при необходимости или заменены/обновлены без перекомпиляции всего приложения.

Некоторые из тех, которые не могут быть ресурсами: cUnderscore, например, выглядит так, будто он использует текст для создания визуального эффекта - как правило, плохая идея.

В защиту вашего предшественника я считаю этот код предпочтительным для нахождения тех же констант, которые разбросаны по всему источнику, так как он сделает рефакторинг ресурсами немного проще.

4

Похоже, что у разработчика был стандарт кодирования, который гласит: «Не используйте строковые литералы в коде и покорно отделяйте каждую константу, независимо от того, имеет ли она смысл или нет.

Например, есть, вероятно, некоторый элемент там, где в коде требуется число 1, а вместо использования DefaultNumberOfLineItems или какой-либо другой описательной константы они использовали NumberOne = 1;

Лучшей практикой будет сохранение констант описательным и близким к их точке использования. Нет ничего плохого в статическом классе связанных констант, которые имеют некоторый тип значения и связаны друг с другом.

Например, существует система, в которой я работал с атрибутами тегов с уникальными ключами. Эти ключи собраны в статическом классе с описательными именами на атрибуты, фактически ключи генерируются автоматизированной системой

public static class AttributeIDs 
{ 
    public const string Name = "UniqueGeneratedKeyForNameAttribute"; 
    public const string Description ="UnqiueGeneratedKeyForDescriptionAttribute"; 
    ... etc. 
} 

На практике это используется как

MyAccess.GetValueForAttribute(AttributeIDs.Name); 

который получает все соответствующие константы вместе.

2

Возможные полезные сценарии для такого класса. Как правило, такие вещи, как «магическое число» или «магические строки», включаются в константы и помещаются в статический (общий) класс. Причина этого заключается в том, чтобы изолировать эти «магические» значения в одном месте и позволить им ссылаться на содержательное имя. (Обычно используется для числовых значений.) В случае строковых значений это помогает гарантировать, что на вещи ссылаются одинаковое значение каждый раз. Лучший пример этого - это строковые ключи в файле app.config.

Это означает, что константы должны использоваться для чего-то, что не изменяется (или редко изменяется, что оно эффективно является постоянным). По большей части строки, которые могут быть изменены (или должны быть локализованы), должны храниться как ресурсы в файле .resx.

+0

ресурсы> константы, и если что-нибудь проще –

+0

@Joel Coehoorn: Я думаю, что это зависит от того, как они используются. Например, обеспечение согласованного имени для множества атрибутов DllImport. Я не могу использовать ресурс для имени DLL, но я могу использовать константу. –

2

Нет ничего плохого в том, что у вас есть библиотека классов констант. Константы - хорошая практика в целом. В конце концов, все перечислены в .NET, и они просто сгруппированы числовыми константами. Наличие зависимости от сборки констант не отличается от любой другой зависимости. Понимание цели констант больше связано с логикой приложения. Я предполагаю, что эти константы позволяют подробное ведение журнала, не заполняя приложение кучей строковых литералов.

2

Это действительно выглядит как наивный реализации строки таблицы.

Значения не являются магическими строками и «легкими» общесистемными изменениями. Я бы сказал, что файл ресурсов проще реализовать и поддерживать.

Является ли реализация вашего коллеги лучшей практикой? Я бы сказал, нет. Используя строковые таблицы, это особенно важно, если вам требуется интернационализация в вашем приложении.

1

Ввод строковых констант в отдельный класс является наилучшей практикой во многих ситуациях, однако это плохой пример. Лучшим способом было бы создать пространство имен StringConstants, а затем организовать строки, чтобы связанные строковые константы были организованы в отдельные классы. Это всего лишь плохая реализация хорошей идеи.

Если глобализация является проблемой, то (как указывали другие), строки должны храниться в файлах ресурсов.

0

Существует два типа констант, доступных в C#: Константы времени компиляции и константы времени выполнения. У них разное поведение, а , используя неправильный, будет стоить вам производительности или правильности. так выбрать правильный постоянного типа вы используете для вашего проекта ..

http://dotnetacademy.blogspot.com/2011/09/constants-in-net.html

1

Мы делаем это для того, чтобы выделить определенные константы базы данных из кода. Эта развязка позволяет нам в будущем обновлять базу данных (в настоящее время MS Access) до чего-то лучшего (вероятно, SQL Server), не изменяя очень большую часть кодовой базы вообще. Вот пример таблицы конкретного блока констант:

Public Class Equalisations 
    Public Const TableName As String = "Equalisations" 
    Public Class SPs 
     Public Const SelectAll As String = General.SPs.Prefix & TableName & General.SPs.SelectAll 
     Public Const SelectDropDownList As String = General.SPs.Prefix & TableName & General.SPs.SelectDropDownList 
     Public Const SelectAllChildRecords As String = General.SPs.Prefix & TableName & General.SPs.SelectAllChildRecords 
     Public Const SelectRecord As String = General.SPs.Prefix & TableName & General.SPs.SelectRecord 
     Public Const SelectMaxId As String = General.SPs.Prefix & TableName & General.SPs.SelectMaxId 
     Public Const InsertRecord As String = General.SPs.Prefix & TableName & General.SPs.InsertRecord 
     Public Const DeleteAllRecords As String = General.SPs.Prefix & TableName & "_DeleteAllRecords" 
    End Class 
    Public Class Cols 
     Public Const CompanyAccountID As String = "CitiAccountID" 
     Public Const NAVDate As String = "NAVDate" 
     Public Const GLCodeID As String = "GLCodeID" 
     Public Const Income As String = "Income" 
     Public Const LoadedFileID As String = "LoadedFileID" 
    End Class 
    Public Class Parms 
     Public Const CompanyAccountID As String = "pCitiAccountID" 
     Public Const NAVDate As String = "pNAVDate" 
     Public Const GLCodeID As String = "pGLCodeID" 
     Public Const Income As String = "pIncome" 
     Public Const LoadedFileID As String = "pLoadedFileID" 
    End Class 
End Class 
Смежные вопросы