Хорошие примеры венгерской нотации?
Этот вопрос заключается в поиске хороших примеров венгерской нотации, чтобы мы могли собрать их коллекцию.
Изменить: я согласен, что венгерский для типов не так уж и необходим, я надеюсь на более конкретные примеры, где он повышает удобочитаемость и удобство обслуживания, как Джоэл приводит в своей статье (согласно моему ответу).
22 ответа
Классическая статья, как уже упоминалось в других венгерских статьях, опубликована на сайте Джоэла:
Проблема с запросом хороших примеров венгерской нотации состоит в том, что у каждого будет свое представление о том, как выглядит хороший пример. Мое личное мнение, что лучшая венгерская нотация - это не венгерская нотация. Изначально нотация предназначалась для обозначения предполагаемого использования переменной, а не ее типа, но обычно она используется для информации о типе, особенно для элементов управления Form (например, txtFirstName для текстового поля для чьего-либо имени). Это делает код менее понятным с точки зрения читабельности (например, "prepIn nounTerms prepOf nounReadability") и рефакторинга для случаев, когда необходимо изменить тип (в Win32 API есть "lParams", которые изменили тип).
Вы, вероятно, должны рассмотреть вопрос об использовании его вообще. Примеры:
- strFirstName - это может быть просто firstName, поскольку очевидно, для чего он нужен, тип не так важен и должен быть очевиден в этом случае. Если не очевидно, IDE может помочь вам в этом.
- txtFirstName - это может измениться на FirstNameTextBox или FirstName_TextBox. Это читается лучше, и вы знаете, что это контроль, а не только текст.
- CAccount - C использовался для имен классов в MFC, но он вам действительно не нужен. Аккаунт достаточно хорош. Имя в верхнем регистре является стандартным соглашением для типов (и они появляются только в определенных местах, поэтому их не спутают со свойствами или методами)
- ixArray (индекс в массив) -
ix
немного неясен. Попробуйте arrayIndex. - usState (небезопасная строка для штата) - выглядит как "Штат США". Лучше иди с государством
_
UnsafeString или что-то. Может быть, даже обернуть его в класс UnsafeString, чтобы хотя бы сделать его безопасным для типов.
п
(для указателя). Это почти единственный префикс, который я использую. Я думаю, что это добавляет много к переменной (например, это указатель) и поэтому должно рассматриваться немного более уважительно.
Венгерский для типов данных несколько устарел, теперь IDE могут сказать вам, что это за тип (всего за несколько секунд, наведя курсор на имя переменной), так что это не так важно. Но обрабатывать указатель так, как будто его данные не годятся, поэтому вы хотите убедиться, что для пользователя очевидно, что это такое, даже если он делает предположения, которые он не должен делать при кодировании.
T
Испорченные данные. Префикс всех данных, поступающих из ненадежного источника, чтобы сделать эту переменную испорченной. Все испорченные данные должны быть очищены перед выполнением реальной работы с ними.
Нет смысла использовать венгерский для обозначения типов, потому что компилятор уже делает это за вас.
Венгерский язык полезен для различения логически разных типов переменных, имеющих одинаковый необработанный тип. Например, если вы используете целые числа для представления координат, вы можете добавить префикс x к координатам x, y к координатам y, а расстояния к d. Таким образом, у вас будет код, который выглядит как
dxHighlight = xStart - xEnd
yHighlight = yLocation + 3
yEnd = yStart + dyHeight
dyCode = dyField * 2
и так далее. Это полезно, потому что вы можете сразу увидеть ошибки: если вы добавляете dy в ay, вы всегда получаете y. Если вы вычтете два x, вы всегда получите dx. Если вы умножаете dy на скаляр, вы всегда получаете dy. И так далее. Если вы видите строку, как
yTop = dyText + xButton
с первого взгляда вы понимаете, что это неправильно, потому что добавлять dy и ax не имеет смысла. Компилятор не смог поймать это за вас, потому что, насколько он может судить, вы добавляете int к int, что нормально.
Я был категорически против венгерской нотации, пока я действительно не начал читать об этом и пытаться понять его первоначальные намерения.
После прочтения поста Джоэлса "Неправильно" и статьи "Возвращение к венгерской нотации" я действительно передумал. Сделано правильно, я считаю, что это должно быть чрезвычайно мощным.
Неправильно от Джоэла Спольски
http://www.joelonsoftware.com/articles/Wrong.html
Возвращение к венгерской нотации
http://codingthriller.blogspot.com/2007/11/rediscovering-hungarian-notation.html
Я верю, что большинство скептиков никогда не пробовали это по-настоящему и не понимают этого по-настоящему. Я хотел бы попробовать это в реальном проекте.
Не используйте языковые префиксы.
Мы используем:
n: номер p: Процент 1=100% (для процентных ставок и т. д.) с: валюта s: строка д: дата е: перечисление o: объект (клиент oCustomer= новый клиент ();) ...
Мы используем одну и ту же систему для всех языков:
SQL С C# Javascript VB6 VB.net ...
Это спасатель жизни.
Венгерская нотация (верблюжья оболочка, как я ее узнал) неоценима, когда вы наследуете программный проект.
Да, вы можете "навести" переменную в своей IDE и узнать, что это за класс, но если вы просматриваете несколько тысяч строк кода, вам не нужно останавливаться на эти несколько секунд - каждую.... один раз.... время....
Помните - вы не пишете код для себя или своей команды в одиночку. Вы также пишете это для человека, который должен взять этот код через 2-5 лет и улучшить его.
Адвокат дьявола: лучший пример венгерской нотации - не использовать ее.:D
Мы не получаем никакого преимущества от использования венгерской нотации с современными IDE, потому что они знают тип. Это добавляет работу при рефакторинге типа для переменной, так как имя также должно быть изменено (и в большинстве случаев, когда вы имеете дело с переменной, вы все равно знаете, какой это тип).
Вы также можете попасть в порядок вопросов с обозначениями. Если вы используете p для указателя и a для адреса, вызываете ли вы переменную apStreet или paStreet? Читаемость снижается, когда у вас нет согласованности, и вы должны использовать ценное пространство ума, когда вам нужно запомнить порядок, в котором вы должны записать нотацию.
Я считаю, что венгерские обозначения иногда могут быть полезны в динамических языках. Я специально думаю о серверной стороне Actionscript (по сути, просто javascript), но он может применяться в другом месте. Поскольку никакой реальной информации о типах нет вообще, венгерская нотация иногда может помочь немного упростить понимание.
Я думаю, что ключевая вещь, которую нужно отнять от статьи Джоэля, связанной выше, и от венгерской нотации в целом, это использовать ее, когда есть что-то неочевидное в переменной.
Один из примеров, приведенный в статье, относится к кодированным и не кодированным строкам, это не значит, что вы должны использовать венгерское "нас" для небезопасных строк и "s" для безопасных строк, это то, что у вас должен быть какой-то идентификатор, указывающий, что строка безопасна или нет. Если он становится стандартом, становится легко увидеть, когда стандарт нарушается.
Единственный венгерский язык, который действительно более полезен, это m_ для переменных-членов. (Я также использую s m_ для статических членов, потому что это "другая" область действия, которая все еще существует.) С широкоэкранными мониторами и компиляторами, которые принимают имена переменных длиной восемь миллиардов символов, сокращать имена типов просто не стоит.
Я считаю, что единственным полезным моментом является объявление элементов управления интерфейсом, txtUsername, txtPassword, ddlBirthMonth. Это не идеально, но это помогает в больших формах / проектах.
Я не использую его для переменных или других элементов, просто для контроля.
м
При использовании ORM (например, гибернации) вы склонны обращаться с управляемыми и неуправляемыми объектами. Изменение управляемого объекта будет отражено в базе данных без явного сохранения, тогда как для работы с управляемым объектом требуется явный вызов сохранения. То, как вы справляетесь с объектом, будет отличаться в зависимости от того, какой он есть.
Ну, я использую его только с переменными управления окном. Я использую btn_, txt_, lbl_ и т. Д., Чтобы определить их. Я также считаю полезным поискать имя элемента управления, набрав его тип (btn_ и т. Д.).
В дополнение к использованию "p" для указателя, мне нравится идея использования "cb" и "cch", чтобы указать, является ли параметр размера буфера (или переменная) количеством байтов или количеством символов (я также видел - редко - "ce" используется для указания количества элементов). Таким образом, вместо передачи типа, префикс передает использование или намерение.
Признаюсь, я не использую префикс так часто, как следовало бы, но мне нравится идея.
Очень старый вопрос, но вот несколько "венгерских" префиксов, которые я регулярно использую:
мой
для локальных переменных, чтобы отличить местность, где имя может иметь смысл в глобальном контексте. Если вы видите myFoo, он используется только в этой функции, независимо от того, что мы делаем с Foos где-либо еще.
myStart = GetTime();
doComplicatedOperations();
print (GetTime() - myStart);
а также
TMP
для временных копий значений в циклах или многошаговых операциях. Если вы видите две переменные tmpFoo более чем на пару строк друг от друга, они почти наверняка не связаны.
tmpX = X;
tmpY = Y;
X = someCalc(tmpX, tmpY);
Y = otherCalc(tmpX, tmpY);
и иногда старые и новые по тем же причинам, что и tmp, обычно в более длинных циклах или функциях.
Я согласен с тем, что венгерские обозначения больше не особенно полезны. Я думал, что его первоначальным намерением было указать не тип данных, а тип сущности. Например, в разделе кода, включающем имена клиентов, сотрудников и пользователя, вы можете назвать локальные строковые переменные cusName, empName и usrName. Это помогло бы различать имена переменных с похожим звучанием. Одинаковые префиксы для сущностей будут использоваться во всем приложении. Однако, когда используется OO и вы имеете дело с объектами, эти префиксы являются избыточными в Customer.Name, Employee.Name и User.Name.
Имя переменной должно описывать, что это такое. Хорошее именование переменных делает венгерскую запись бесполезной.
Однако иногда вы используете венгерскую нотацию в дополнение к хорошему именованию переменных. m_numObjects имеет два префикса: m_ и num. m_ указывает область действия: это элемент данных, связанный с этим. num указывает значение.
Я совсем не чувствую затруднений, когда читаю "хороший" код, даже если он содержит некоторый "венгерский". Правильно: я читаю код, я не нажимаю на него. (На самом деле, я почти никогда не использую свою мышь при кодировании или какие-либо функции поиска, специфичные для программирования вуду.)
Я замедляюсь, когда читаю такие вещи, как m_ubScale (да, я смотрю на тебя, Лиран!), Так как я должен посмотреть на его использование (без комментариев!), Чтобы выяснить, что он масштабирует (если вообще?), И это тип данных (который является символом с фиксированной запятой). Лучшее имя будет m_scaleFactor или m_zoomFactor, с комментарием в качестве числа с фиксированной запятой или даже typedef. (На самом деле, typedef был бы полезен, так как есть несколько других членов нескольких классов, которые используют один и тот же формат с фиксированной запятой. Однако некоторые этого не делают, но все еще помечены как m_ubWh независимо! Смущает, если не сказать больше.)
Я думаю, что венгерский язык должен был быть добавкой к имени переменной, а не заменой информации. Кроме того, много раз венгерская нотация вообще ничего не добавляет к читабельности переменной, тратит байты и время чтения.
Просто мои 2¢.
Я только когда-либо использую p для указателя, и это все. И это только если я в C++. В C# я не использую венгерскую нотацию. например
MyClass myClass;
MyClass* pMyClass;
Это все:)
Редактировать: О, я только что понял, что это ложь. Я использую "m_" для переменных-членов тоже. например
class
{
private:
bool m_myVar;
}
Я обнаружил, что использую "w", что означает "работающий", вместо префикса "temp" или "tmp" в качестве префикса для локальных переменных, которые просто существуют для разыгрывания данных, например:
Public Function ArrayFromDJRange(rangename As Range, slots As Integer) As Variant
' this function copies a Disjoint Range of specified size into a Variant Array 7/8/09 ljr
Dim j As Integer
Dim wArray As Variant
Dim rCell As Range
wArray = rangename.Value ' to initialize the working Array
ReDim wArray(0, slots - 1) ' set to size of range
j = 0
For Each rCell In rangename
wArray(0, j) = rCell.Value
j = j + 1
Next rCell
ArrayFromDJRange = wArray
End Function
Нет такого понятия, как хороший пример венгерской нотации. Просто не используйте это. Даже если вы используете слабо типизированный язык. Вы будете жить счастливее.
Но если вам действительно нужна какая-то причина, чтобы не использовать его, это мой любимый, извлеченный из этой замечательной ссылки:
Следующим трюком в венгерской нотации является "изменить тип переменной, но оставить имя переменной без изменений". Это почти всегда выполняется в приложениях Windows с переходом с Win16:- WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam) на Win32 WndProc(HWND hW, UINT wMsg, WPARAM wParam, LPARAM lParam), где значения w h что это слова, но они действительно относятся к длинным. Реальная ценность этого подхода становится ясной с миграцией Win64, когда параметры будут иметь ширину 64 бита, но старые префиксы "w" и "l" останутся навсегда.