Какая польза от использования венгерской нотации?


101

Одна из вещей, с которой я борюсь, это не использование венгерской нотации. Я не хочу идти к определению переменной, чтобы посмотреть, какой это тип. Когда проект становится обширным, приятно иметь возможность просматривать переменную с префиксом 'bool' и знать, что он ищет значение true / false вместо значения 0/1 .

Я также много работаю в SQL Server. Я добавляю к моим хранимым процедурам 'sp', а мои таблицы к 'tbl', не говоря уже о всех моих переменных в базе данных соответственно.

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


39
Какой язык / IDE вы используете? В Visual Studio вам не нужно переходить к определению, чтобы узнать тип переменной, поскольку среда IDE предоставляет ее вам. В языках, где типы не применяются принудительно, например, в PHP, вам не нужно знать тип большую часть времени (так как вы можете присвоить 0 или 1 логическому значению).
Арсений Мурзенко

10
@MainMa Я не уверен, что это хорошая причина не знать тип значения в PHP.
Рей Миясака

29
«Когда проекты становятся обширными» ... не должно иметь значения. В любой точке должно быть только небольшое количество переменных: несколько переменных класса и еще несколько аргументов метода. Если вы не можете держать их прямо, значит, класс слишком велик или метод слишком длинный. Венгерская нотация была изобретена для программирования на Windows C, в основном как обходной путь для ужасного Windows API. Ничего подобного никогда не предлагалось и не требовалось для разработки под Unix.
Кевин Клайн

20
какая польза от использования венгерской нотации «не ненавидят ваши коллеги» приходит на ум ...
Шон Патрик Флойд

25
примечание к югу от венгерского языка
Ден04

Ответы:


148

Поскольку его первоначальное намерение (см. Http://www.joelonsoftware.com/articles/Wrong.html и http://fplanque.net/Blog/devblog/2005/05/11/hungarian_notation_on_steroids ) было неправильно понято и оно было ( ab) используется, чтобы помочь людям запомнить, какой тип переменной, когда язык, который они используют, не является статически типизированным. В любом статически типизированном языке вам не нужно добавлять балласт префиксов, чтобы сказать вам, какой тип является переменной. Во многих нетипизированных языках сценариев это может помочь, но им часто злоупотребляют до такой степени, что они становятся совершенно громоздкими. К сожалению, вместо того, чтобы вернуться к первоначальному замыслу венгерской нотации, люди просто превратили это в одну из тех «злых» вещей, которых вам следует избегать.

Короче говоря, венгерская нотация была предназначена для префикса переменных с некоторой семантикой. Например, если у вас есть экранные координаты (левый, верхний, правый, нижний), вы должны поставить префикс переменных с абсолютными позициями на экране « abs», а переменных с позициями относительно окна с « rel». Этот путь будет очевиден для любого читателя, когда вы передадите относительную координату в метод, требующий абсолютных позиций.

обновление (в ответ на комментарий delnan)

ИМХО, следует избегать злоупотребления версией, как чумы, потому что:

  • это усложняет наименование. Когда (ab) используется венгерская нотация, всегда будут дискуссии о том, насколько конкретными должны быть префиксы. Например: listboxXYZили MyParticularFlavourListBoxXYZ.
  • это делает имена переменных длиннее, не помогая понять, для чего переменная.
  • это своего рода побеждает объект упражнения, когда во избежание длинных префиксов они сокращаются до сокращений, и вам нужен словарь, чтобы знать, что означает каждое сокращение. Есть uiцелое число без знака? неисчисляемый подсчитанный интерфейс? что-то делать с пользовательскими интерфейсами? И эти вещи могут стать длинными . Я видел префиксы из более чем 15, казалось бы, случайных символов, которые должны передавать точный тип переменной, но на самом деле только мистифицировать.
  • это быстро устаревает. Когда вы изменяете тип переменной, люди всегда (lol) забывают обновить префикс, чтобы отразить изменение, или намеренно не обновлять его, потому что это вызовет изменения кода везде, где используется var ...
  • это усложняет разговор о коде, потому что "@g." сказал: имена переменных с венгерской нотацией, как правило, трудно произносимый алфавитный суп. Это мешает удобочитаемости и обсуждению кода, потому что вы не можете «сказать» ни одно из имен.
  • ... многое другое, что я не могу вспомнить в данный момент. Возможно, потому что я имел удовольствие не иметь дело с оскорбленной венгерской нотацией в течение долгого времени ...

9
@ Surfer513: На самом деле, я предпочитаю суффиксы при именовании элементов управления. Для меня гораздо интереснее найти все элементы управления, которые имеют дело с определенной темой / аспектом, чем найти все элементы управления для редактирования ... Когда я хочу найти элемент управления, где пользователь может ввести имя клиента, я начну искать клиент, а не TXT, потому что это может быть не TXT (правка), а памятка, или richedit, или ... Может даже быть поле со списком, чтобы позволить найти его в ранее введенных именах клиентов ...
Marjan Venema

8
@ Surfer513: И в настоящее время я склонен использовать суффиксы только при различении двух элементов управления, имеющих дело с одной и той же вещью. Например, метка и редактирование имени клиента. И довольно часто суффиксы связаны не с типом элемента управления, а с его назначением: например, ClientCaption и ClientInput.
Марьян Венема

3
Также стоит отметить, что intellisense в VS 2010 позволяет искать по всему имени, а не только по началу. Если вы назовете свой элемент управления «firstNameTextBox» и введете «textb», он найдет ваш элемент управления и выведет его список.
Адам Робинсон

4
«... оскорбленной версии избегают, как зубного налета ...», то есть избегают немного реже, чем зубной камень и гингивит? ;-)
Бен Мошер

4
@Marjan: Конечно, компилятор мог бы понять это. Если каждая единица представлена ​​типом, то вы не можете случайно передать один за другим. Здесь, если у вас есть a AbsoluteXTypeи a RelativeYType, вы не могли по ошибке передать относительную координату Y для абсолютной координаты X. Я предпочитаю, чтобы переменные, представляющие несовместимые объекты, имели несовместимые типы, а не имели несовместимые префиксы. Компилятор не заботится о префиксах (или суффиксах).
Матье М.

74

Венгерская нотация - это анти-шаблон именования в современных средах программирования и форме тавтологии .

Он бесполезно повторяет информацию без пользы и дополнительных затрат на обслуживание. Что происходит, когда вы меняете intтип на другой, например long, теперь вам нужно искать и заменять всю базу кода, чтобы переименовать все переменные, или они теперь семантически неверны, что хуже, чем если бы вы не дублировали тип в имени.

Это нарушает принцип СУХОГО. Если вам необходимо добавить в префикс таблиц базы данных аббревиатуру, чтобы напомнить вам, что это таблица, то вы определенно недостаточно семантически называете свои таблицы. То же самое касается любой другой вещи, с которой вы делаете это. Это просто дополнительный набор текста и работа без какой-либо выгоды или выгоды в современной среде разработки.


2
«Что происходит, когда вы меняете свой intтип на другой, например long...» Простой: <sarcasm> Не меняйте имя, потому что не известно, сколько мест будет изменяться. </ Sarcasm> Так что теперь у вас есть переменная, Венгерское название противоречит его реализации. Нет абсолютно никакого способа сказать, насколько широко будут сказываться эффекты изменения имени, если переменная / функция будет общедоступной.
Дэвид Хаммен

2
Связанная статья является фантастической, и ее стоит прочитать. +1
Марти Питт

6
@David просто посмотрите на Win32 API, который пронизан переменными, параметрами и даже именами методов, которые с использованием венгерской нотации (что является обязательным требованием в MS) указывают на 8-битное или 16-битное значение, хотя на самом деле все они были 32-битными значения с момента появления Windows 95 еще в 1994 году (так почти 17 лет назад).
Вечером

2
@Secure: я бы сказал, что именно этим должны заниматься автоматизированные тесты. Не программисты.
Джоэл

2
@Secure возможно не в собственном приложении, но если вы поддерживаете открытый API, такой как Windows API, это большая проблема.
jwenting

51

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

Выгода не используя Венгерская нотация в основном только избегание его недостатков:

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

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

  • Венгерская нотация сбивает с толку, когда она используется для представления нескольких свойств, таких как a_crszkvc30LastNameCol: постоянный ссылочный аргумент, содержащий содержимое столбца базы данных LastNameтипа, varchar(30)который является частью первичного ключа таблицы.

  • Это может привести к несогласованности при изменении или переносе кода. Если тип переменной изменяется, либо оформление имени переменной будет несовместимо с новым типом, либо имя переменной должно быть изменено. Особенно хорошо известным примером является стандартный WPARAMтип и сопутствующий wParamформальный параметр во многих объявлениях системных функций Windows. «W» означает «слово», где «слово» - это собственный размер слова аппаратной архитектуры платформы. Первоначально он был 16-разрядным типом для 16-разрядных архитектур слов, но был изменен на 32-разрядный для 32-разрядных архитектур слов или 64-разрядным типом для 64-разрядных архитектур слов в более поздних версиях операционной системы при сохранении ее оригинальное имя (его истинный базовый типUINT_PTRто есть целое число без знака, достаточно большое, чтобы содержать указатель). Семантический импеданс и, следовательно, путаница и несоответствие программиста от платформы к платформе, основаны на предположении, что «w» означает 16-битный в этих различных средах.

  • В большинстве случаев знание использования переменной подразумевает знание ее типа. Кроме того, если использование переменной неизвестно, она не может быть выведена из ее типа.

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

  • Это делает код менее читаемым, запутывая назначение переменной ненужными префиксами типа и области видимости.

  • Дополнительная информация о типе может недостаточно заменить более описательные имена. Например sDatabase, не говорит читателю, что это такое. databaseNameможет быть более описательным именем.

  • Когда имена достаточно описательны, дополнительная информация о типе может быть избыточной. Например, firstNameэто, скорее всего, строка. Таким образом, присвоение имен sFirstNameтолько добавляет беспорядка в код.

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


1
Это должен быть правильный ответ. Это так приятно. +1
Саид Нимати

Ты слишком добр, Саид. Я ценю вашу благодарность, но другие ответы на этот вопрос тоже очень хороши.
Сокол

11
Голосование за одно предложение: «В большинстве случаев знание использования переменной подразумевает знание ее типа. Кроме того, если использование переменной неизвестно, ее нельзя определить из ее типа». - ИМХО, это причина № 1, чтобы избежать венгерской нотации.
Даниэль Приден

19

Как специфическая проблема MS SQL Server:

Любые хранимые процедуры с префиксом «sp_» сначала ищутся в базе данных Master, а не в той, в которой они созданы. Это приведет к задержке выполнения хранимой процедуры.


4
+1 за очень классную информацию там. Я использую 'sp' в качестве своего сохраненного префикса proc, а не 'sp_'. Но, тем не менее, это определенно очень очень интересный факт и конкретная причина не использовать sp_ в качестве хранимого префикса proc.

2
+1 Я никогда не знал этого, и когда я начал работать над SQL Server, все SP на моем рабочем месте были с префиксом, sp_поэтому я просто придерживался соглашения.
Майкл

Отличный момент, но ничего общего с этим вопросом (используя sq, а не _sp). Это все равно, что не указывать имя схемы для объектов, которых нет в схеме по умолчанию.
JeffO

1
Для пользовательских хранимых процедур я обычно использовал «usp_». Это служило для того, чтобы избежать упомянутой проблемы И различить для читателя, был ли sproc системным или пользовательским.
Зонт

15

ИМО самым большим преимуществом неиспользования венгерского языка является тот факт, что он заставляет вас использовать значимые имена . Если вы правильно называете переменные, вы должны немедленно знать, какой это тип, или иметь возможность довольно быстро вывести их в любой хорошо спроектированной системе. Если вам нужно полагаться на strили blnили хуже всех objпрефиксов , чтобы знать , какой тип переменной, я бы утверждать , что это указывает на проблему присвоения имен - либо плохие имена переменных в целом или слишком общими , чтобы передать смысл.

По иронии судьбы, исходя из личного опыта, основной сценарий, который я видел на венгерском языке, это либо «грубо-культовое» программирование (т. Е. Другой код использует его, так что давайте продолжим использовать его только потому, что), либо в VB.NET, чтобы обойти тот факт, что язык без учета регистра (например, Person oPerson = new Personпотому что вы не можете использовать Person person = new Personи Person p = new Personслишком расплывчато); Я также видел префикс «или» вместо «как» Person thePerson = new Personили «уродливее» Person myPerson = new Person, в данном конкретном случае.

Я добавлю единственный раз, когда я использую венгерский, как правило, для элементов управления ASP.NET, и это действительно вопрос выбора. Мне очень некрасиво набирать текст TextBoxCustomerNameили CustomerNameTextBoxсравнивать с более простым txtCustomerName, но даже это кажется «грязным». Я считаю, что для элементов управления следует использовать какое- то соглашение об именах, поскольку может быть несколько элементов управления, отображающих одни и те же данные.


13

Я просто сосредоточусь на SQL Server, так как вы упомянули об этом. Я не вижу смысла ставить табличку перед столом. Вы можете просто посмотреть на любой код tSQL и различить таблицу по тому, как он используется. Вы никогда не захотите Select from stored_procedure.или не Select from table(with_param)захотите использовать UDF или Execute tblTableOrViewNameхранимую процедуру.

Таблицы могут быть перепутаны с View, но когда дело доходит до того, как они используются; разницы нет, так какой смысл? Венгерская нотация может сэкономить вам время на поиск в SSMS (под таблицей или представлениями?), Но это все.

Переменные могут представлять проблему, но они должны быть объявлены, и действительно, как далеко от вашего оператора объявлять вы планируете использовать переменную? Прокрутка нескольких строк не должна быть слишком сложной, если вы не пишете очень длинные процедуры. Это может быть хорошей идеей немного разбить длинный код.

То, что вы описываете, - это боль, но решение венгерской нотации не решает проблему. Вы можете взглянуть на чужой код и обнаружить, что тип переменной может измениться, что теперь требует изменения имени переменной. Еще одна вещь, которую нужно забыть. И если я использую VarChar, то вам все равно придется взглянуть на заявление объявления, чтобы узнать размер. Описательные имена, вероятно, помогут вам продвинуться дальше. @PayPeriodStartDate в значительной степени объясняет себя.


2
@Surfer: первичный ключ отличается, потому что «PK» не тип; «PK_TableName» говорит «это первичный ключ для TableName», а не «это TableName типа PK». В остальном ... не похоже, что вы действительно слушаете аргументы здесь. Пожалуйста, прекратите использовать эту отвратительную практику, которая по сей день продолжает снижать общее качество всего кода.
Aaronaught

2
@Aaronaught, вы указываете один аспект венгерской нотации ( en.wikipedia.org/wiki/Hungarian_notation ). Это не просто тип, но и предполагаемое использование. Таким образом, префикс «pk» для первичного ключа фактически является венгерской нотацией. Я слушаю аргументы здесь, но есть исключения (например, ситуация с первичным ключом), когда кажется, что HN выгоден. Может быть, а может и нет. Я все еще пытаюсь обернуть голову вокруг дел и не для всех сценариев. Сегодня я узнал немного об этом и вызвал некоторые большие мысли.

3
@ Surfer: это просто не правильно. Венгерская нотация описывает либо тип (плохая версия), либо конкретное использование типа (менее плохая версия). PK - это не просто, это не просто описание чего-то типа, это описание поведения . Когда я говорю, скажем, о возрасте, совершенно неинтересно, что это целое число, но когда речь идет об ограничении базы данных, «первичный ключ для таблицы X» - это именно то, что важно.
Аарона

4
Мне нравится ваш второй до последнего абзаца. Моя фирма обосновывает использование венгерской нотации: «Это позволяет нам быстро увидеть, какие переменные являются глобальными, а какие нет». А затем вы смотрите на объявления переменных, и в каждом файле есть 300 переменных, некоторые m * для модульных (глобальных), некоторые v * для локальных ДАЖЕ, ЧТО ОНИ ОБЪЯВЛЕНЫ НА МОДУЛЬНОМ УРОВНЕ. «О, это потому, что они просто предназначены для использования в качестве местных, а не модульных». Facepalm
corsiKa

3
@Aaronaught: В моем текущем проекте мы используем имена таблиц с префиксом tbl_ . Хотя я не большой поклонник этой практики, я не вижу, как это «снижает общее качество всего кода» . Можете ли вы привести пример?
Треб

6

Еще одна вещь, которую нужно добавить, это то, какие сокращения вы бы использовали для целого фреймворка, такого как .NET? Да, это так просто запомнить, что btnпредставляет собой кнопку и txtпредставляет собой текстовое поле. Однако что вы имеете в виду для чего-то подобного StringBuilder? strbld? Как насчет CompositeWebControl? Вы используете что-то вроде этого:

CompositeWebControl comWCMyControl = new CompositeWebControl();

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


6

На мой взгляд, венгерская нотация - это препятствие для обхода недостаточно мощной системы типов. В языках, которые позволяют вам определять свои собственные типы, довольно просто создавать новый тип, который кодирует поведение, которое вы ожидаете. В статье Рунта Джоэла Спольски о венгерской нотации он приводит пример использования его для обнаружения возможных XSS-атак, указывая, что переменная или функция либо небезопасны (мы), либо безопасны (ы), но при этом все равно полагается на визуальную проверку программистом. Если вместо этого у вас есть расширяемая система типов, вы можете просто создать два новых типа, UnsafeString и SafeString, а затем использовать их по мере необходимости. В качестве бонуса тип кодирования становится:

SafeString encode(UnsafeString)

и если не получить доступ к внутренним объектам UnsafeString или использовать некоторые другие функции преобразования, это станет единственным способом перехода от UnsafeString к SafeString. Если все ваши выходные функции работают только с экземплярами SafeString, становится невозможным вывести неэкранированную строку [исключая махинации с такими преобразованиями, как StringToSafeString (someUnsafeString.ToString ())].

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

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

Что касается другой интерпретации венгерской нотации, то есть, когда IE префиксирует тип переменной, это просто глупо и поощряет ленивые практики, такие как присвоение имен переменным uivxwFoo, а не что-то значимое, например countOfPeople.


Как можно объявить тип .NET или Java для описания « int[]который может быть свободно изменен, но никогда не передан» или « int[]который может быть свободно распространен только среди вещей, которые никогда не изменят его»? Если int[]поле fooинкапсулирует значения, {1,2,3}можно ли сделать его инкапсулированным, {2,2,3}не зная, какой его «тип» int[]представляет? Я думаю, что Java и .NET были бы намного лучше, если бы - в отсутствие поддержки системы типов они, по крайней мере, приняли соглашение об именах, чтобы различать эти типы.
суперкат

4

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

В динамически типизированных языках это может иногда помогать, но для меня это кажется недиоматичным. Вы уже отказались от своих функций, ограниченных точными доменами / доменами; если все ваши переменные названы с венгерской нотацией, то вы просто воспроизводите то, что дала бы вам система типов. Как вы выражаете полиморфную переменную, которая может быть целым числом или строкой в ​​венгерской нотации? "IntStringX"? "IntOrStringX"? Единственное место, где я когда-либо использовал венгерскую нотацию, было в ассемблерном коде, потому что я пытался вернуть то, что получил бы, если бы у меня была система типов, и это было первое, что я когда-либо кодировал.

В любом случае, меня не волнует, как люди называют свои переменные, код, вероятно, все еще будет таким же непонятным. Разработчики тратят слишком много времени на такие вещи, как стили и имена переменных, и, в конце концов, вы по-прежнему получаете массу библиотек с совершенно другими соглашениями на вашем языке. Я разрабатываю символический (т.е. не основанный на тексте) язык, в котором нет имен переменных, только уникальные идентификаторы и предлагаемые имена для переменных (но большинство переменных по-прежнему не имеют предлагаемого имени, потому что просто не существует разумного имени для их); при проверке ненадежного кода вы не можете зависеть от имен переменных.


Это также довольно бесполезно для большинства динамически типизированных языков!
Джеймс Андерсон

2
для IDE это даже хуже, чем для ручного кодирования, поскольку это означает, что завершение кода значительно замедляется. Если у вас есть 100 целочисленных переменных, набрав int <alt-space> (например), вы получите 100 элементов для прокрутки. Если вам нужен intVeryLongVariableName, ваше завершение кода становится проблематичным. Без венгерского языка вы просто набрали бы очень <alt-space> и имели бы только 1 или 2 варианта.
Вечером

3

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

Я вижу три "ошибки" в вашем видении: 

1) Если вы хотите узнать тип переменной / параметра / атрибута / столбца, вы можете навести указатель мыши или щелкнуть ее, и она будет отображаться в большинстве современных IDE. Я не знаю, какие инструменты вы используете, но в прошлый раз я был вынужден работать в среде, которая не предоставляла эту функцию, в 20-м веке, язык был COBOL, ой, нет, это был Fortran, и мой босс не понял, почему я ушел. 

2 / Типы могут меняться в течение цикла разработки. В какой-то момент 32-разрядное целое число может стать 64-разрядным целым числом по уважительным причинам, которые не были обнаружены в начале проекта. Таким образом, переименование intX в longX или оставление его с именем, указывающим на неправильный тип, является плохой кармой. 

3) На самом деле вы запрашиваете избыточность. Избыточность не очень хороший дизайн шаблона или привычки. Даже люди не хотят слишком много избыточности. Даже люди не хотят слишком много избыточности. 


Я понимаю продвинутый / современный IDE и полностью согласен с вами. Но как насчет дизайна базы данных? Допустим, у вас есть столбец или параметр хранимой процедуры. Наведение над трюком на самом деле не работает с такими вещами. Вы должны посмотреть на определение таблицы / хранимой процедуры. Что ты для этого делаешь?

3

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

Если определение вашей переменной не видно, обычно у вас проблемы.
И если ваши функции не следуют какой-то запоминающейся конвенции , опять же, большие проблемы.

Это ... во многом причина того, что многие рабочие места справляются с этим, я полагаю.

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

Единственное реальное использование у нас есть для этого сегодня является Джоэл Спольски один .
Чтобы отслеживать некоторые конкретные атрибуты переменной, например, ее безопасность .

( например, «Имеет ли переменная safeFoobarзеленый свет для вставки в SQL-запрос?
- Как она называется safe, да»)

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


2

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

С базами данных я использую венгерскую нотацию для объектов DDL, которые редко используются в коде, но в противном случае столкнулись бы в пространствах имен. В основном это сводится к тому, что индексам и именным ограничениям присваивается префикс с их типом (PK, UK, FK и IN). Используйте согласованный метод для именования этих объектов, и вы сможете выполнять некоторые проверки, запрашивая метаданные.


Я часто нахожу это в том случае, когда у меня есть таблица идентификаторов. Если бы у меня был TABLE SomeStringById(int somestringId, varchar somestring)индекс, он также был бы логически, SomeStringByIdно это вызывает коллизию. Так я это называю idx_SomeStringById. Затем, чтобы последовать их примеру, я сделаю это idx_SomeStringByValueтолько потому, что глупо иметь idx_один, а не другой.
CorsiKa

1

причина, по которой этого избегают, заключается в том, что венгерский язык системы нарушает DRY (префикс - это именно тот тип, который может получить компилятор и (хорошая) IDE)

приложения венгерские префиксы OTOH с использованием переменной (то есть scrxMouse - это координата топора на экране, это может быть тип int, short, long или даже пользовательский тип (typedefs даже позволит вам легко его изменить))

неправильное понимание систем - то, что разрушило венгерский язык как лучшую практику


2
Я должен не согласиться - что разрушило венгерский язык как «лучшую практику», так это то, что она никогда не была близка к лучшей (или даже хорошей) практике.
Джерри Гроб

2
@haylem: я видел статьи, оригинальную статью Симони и читал код. Каждый раз, когда вы смотрите на это, это плохая идея, которая никогда не должна была увидеть свет.
Джерри Гроб

1
Это не обязательно нарушает DRY в динамическом языке; это просто однотипно. СУХОЙ не всегда хорошо; пример: C макросы.
Longpoke

3
ИМО, что «разрушило» венгерский, так это то, что даже «намерение» бесполезно по сравнению с использованием описательных имен , хотя, если честно, когда создавался венгерский язык, не было движения за наличие читаемого кода ...
Уэйн Молина

1
@Wayne M: «описательные имена» легко сказать, когда компиляторы по существу позволят вам использовать эссе для имени переменной. Когда длина имен идентификаторов фактически ограничивается низким, довольно произвольное значение (я думаю, что общий предел было восемь или десять символов не что очень давно, я , кажется, припоминаю , что Borland Turbo C 2 даже был вариант конфигурации для максимальная длина имени идентификатора!), кодирование полезной информации в имени было немного хитрее ...
CVn

1

Допустим, у нас есть такой метод (в C #):

int GetCustomerCount()
{
    // some code
}

Теперь в коде мы называем это так:

var intStuff = GetCustomerCount();
// lots of code that culminates in adding a customer
intStuff++;

ИНТ не говорит нам очень много. Тот факт, что что-то является int, не говорит нам, что в нем. Теперь давайте предположим, что вместо этого мы называем это так:

var customerCount = GetCustomerCount();
// lots of code that culminates in adding a customer
customerCount++;

Теперь мы можем видеть, какова цель переменной. Было бы важно, если бы мы знали, что это int?

Первоначальная цель венгерского языка состояла в том, чтобы вы сделали что-то вроде этого:

var cCustomers = GetCustomerCount();
// lots of code that culminates in adding a customer
cCustomers++;

Это хорошо, если вы знаете, что означает c . Но у вас должна быть стандартная таблица префиксов, и каждый должен будет их знать, и любой новый человек должен будет выучить их, чтобы понять ваш код. Тогда как customerCountили countOfCustomersэто довольно очевидно на первый взгляд.

Венгерский имел некоторое назначение в VB до того, как Option Strict Onсуществовал, потому что в VB6 и более ранних версиях (и в VB .NET с Option Strict Off) VB приводил к типам, поэтому вы можете сделать это:

Dim someText As String = "5"
customerCount = customerCount + someText

Это плохо, но компилятор вам об этом не скажет. Так что, если бы вы использовали венгерский, по крайней мере, у вас был бы какой-то индикатор того, что происходило:

Dim strSomeText As String = "5"
intCustomerCount = intCustomerCount + strSomeText  // that doesn't look right!

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


1

Я нашел много хороших аргументов против, но один я не видел: эргономика.

В прежние времена, когда все, что у вас было, было string, int, bool и float, символов sibf было бы достаточно. Но со строкой + short начинаются проблемы. Использовать полное имя для префикса или str_name для строки? (Хотя имена почти всегда являются строками - не так ли?) Что с классом Street? Имена становятся длиннее и длиннее, и даже если вы используете CamelCase, трудно сказать, где заканчивается префикс типа и где начинается имя переменной.

 BorderLayout boderLayoutInnerPanel = new BorderLayout ();
 panelInner.addLayout (borderLayoutInnerPanel);

Хорошо, вы можете использовать подчеркивание, если вы не используете их для чего-то другого, или использовать CamelCase, если вы использовали подчеркивание так долго:

 BorderLayout boderLayout_innerPanel = new BorderLayout ();
 panel_inner.addLayout (borderLayout_innerPanel);

 Border_layout boder_layoutInner_panel = new Border_layout ();
 panelInner.add_layout (border_layoutInner_panel);

Это чудовищно, и если вы сделаете это последовательно, у вас будет

 for (int iI = 0; iI < iMax-1; ++iI)
     for (int iJ = iI; iJ < iMax; ++iMax) 
          int iCount += foo (iI, iJ); 

Либо вы закончите использование бесполезных префиксов для тривиальных случаев, таких как переменные цикла или count. Когда вы недавно использовали короткое или длинное для счетчика? Если вы делаете исключения, вы часто теряете время, думая о том, нужен префикс или нет.

Если у вас много переменных, они обычно группируются в браузере объектов, который является частью вашей IDE. Теперь, если 40% начинаются с i_ для int, и 40% с s_ для строки, и они отсортированы в алфавитном порядке, трудно найти значительную часть имени.


1

Единственное место, где я до сих пор регулярно использую венгерские или аналогичные суффиксы, - это контексты, в которых одни и те же семантические данные представлены в двух разных формах, таких как преобразование данных. Это может быть в случаях, когда существует несколько единиц измерения, или когда существует несколько форм (например, строка «123» и целое число 123).

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

Исходный код программы - это собственный пользовательский интерфейс, отображающий алгоритмы и метаданные для сопровождающего, а избыточность пользовательских интерфейсов - достоинство, а не грех . Посмотрите, например, картинки в « Дизайн повседневных вещей », и посмотрите на двери с надписью «Толчок», которые выглядят так, как будто вы их тянете, и на пивные краны, которые операторы взломали на важные элементы управления ядерного реактора, потому что они каким-то образом «зависли». их в IDE "не было достаточно хорошо.

«Просто парить в IDE» - это не причина не использовать венгерский язык, а лишь причина, по которой некоторые люди могут не найти это полезным. Ваш пробег может отличаться.

Идея о том, что венгерский налагает существенную нагрузку на обслуживание при смене типов переменных, глупа - как часто вы меняете типы переменных? Кроме того, переименование переменных легко:

Просто используйте IDE, чтобы переименовать все случаи. -Гандер, отвечая Гусю

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.