Чому я не повинен використовувати «Угорську нотацію»?


122

Я знаю, на що посилається угорська - надання інформації про змінну, параметр або тип як префікс до назви. Кожен, здається, жорстоко проти цього, хоча в деяких випадках це здається гарною ідеєю. Якщо я відчуваю, що корисна інформація передається, чому б я не ставлю її там, де вона є?

Дивіться також: Чи використовують люди угорські конвенції про іменування в реальному світі?


Відповіді:


174

Більшість людей неправильно використовують угорські позначення і отримують неправильні результати.

Прочитайте цю чудову статтю Джоела Спольського: Зробити неправильний код невірним .

Коротше кажучи, угорська нотація, де ви префіксуєте назви змінних за допомогою їх type(рядка) (Система Угорська), погана, оскільки марна.

Угорська нотація, як її задумав її автор, де ви префіксуєте ім'я змінної разом із її kind(використовуючи приклад Джоеля: безпечний рядок або небезпечний рядок), так званий Apps Hungarian має свої користі та все ще є цінним.


5
Хороша посилання, хороший підсумок того, що стоїть за посиланням, і ніякого фанатизму. Відмінно.
Дастман

12
Зауважте, що приклад Joels є у VBScript, мові, яка давно не мала визначених користувачем класів. У мові OO ви просто створите тип HtmlEncodedString і метод Write прийме лише це. "Угорська програма" корисна лише мовами без визначених користувачем типів.
ЖакБ

4
Майкрософт відомий своїм минулим зловживанням угорською нотацією. Попередження інформації про тип до ідентифікаторів не тільки марно, але може фактично принести шкоду. По-перше, читабельність менш вільна. По-друге, мовами, які підтримують поліморфізм або набирання качок неправильної інформації, передається.
wilhelmtell

9
Мені все одно подобається використовувати угорські позначення, якщо я займаюся прямою розробкою C зі старішою IDE ... таким чином я знаю, що немає проблем із кастингом типу.
Звуковий сигнал

3
@Krumia: Це, як правило, можна запобігти, якщо в першу чергу мають описові назви змінних. Але якщо ви хочете бути впевнені, було б набагато безпечніше створити різні типи (наприклад, конструкції) для довжини, ваги тощо і використовувати перевантаження оператора, щоб гарантувати, що можливі лише дійсні операції.
ЖакБ

277

v Використання прим. Угорська примітка vmakes nreading ncode adjdifficult.


101
Приємна аналогія, хоча і трохи несправедлива. Порівняйте: v Використання пристосуванняВенгерська nНотація vMakes nПрочитати nCode adjDifficult.
Кріс Ное

27
У цьому реченні і Використання, і Читання є дієприслівниками. Але я розумію, що ви робили ...
шимпанзе

28
@chimp: це робить речі ще більш очевидними. тепер, коли ви знайшли помилку в типі, збираєтесь перейменовувати всі посилання або залишити їх такими, якими вони є, надаючи дезінформацію? ви втрачаєте будь-який спосіб. але, звичайно, це неправильний спосіб застосування угорських позначень.
wilhelmtell

1
@Chris Noe: для певних стилів читання (проаналізуйте префікс та суфікс поглядом на середину) ваш приклад лише погіршує ситуацію. Я бачу "вживання" і чую "голосування" в голові.
Боб Крос

3
@Jon: якщо у вас є ім'я змінної, яке не повністю видає те, що вона представляє, то, безумовно, слід зосередити увагу на тому, щоб перейменувати її на щось більш описове (і угорська позначення не є вдосконаленням саме по собі найкращий випадок - це виправлення симптому - не вирішення проблеми).
hlovdal

104

Джоель помиляється, і ось чому.

Ця інформація про програму, про яку він говорить, повинна бути закодована в системі типів . Ви не повинні залежати від перегортання імен змінних, щоб не передати небезпечні дані функціям, що вимагають безпечних даних. Ви повинні зробити це помилкою типу, щоб зробити це неможливо . Будь-які небезпечні дані повинні мати тип, який позначений як небезпечний, так що він просто не може бути переданий безпечній функції. Для перетворення з небезпечного в безпечне потрібно вимагати обробки з якоюсь функцією санітарії.

Багато речей, про які Джоель говорить як про "види", не є видами; вони, власне, типи.

Однак у більшості мов бракує системи типів, достатньо виразної для застосування подібних відмінностей. Наприклад, якби C мав вид "strong typedef" (де ім'я typedef виконувало всі операції базового типу, але не було його конвертованим), багато з цих проблем піде назовні. Наприклад, якщо ви можете сказати, strong typedef std::string unsafe_string;щоб запровадити новий тип, unsafe_stringякий не можна було б перетворити на std :: string (і тому він міг би брати участь у вирішенні перевантажень і т. Д.), Тоді нам не потрібні дурні префікси.

Отже, центральне твердження, що угорська мова для речей, які не є типами, є помилковим. Він використовується для інформації про тип. Інформація багатшого типу, ніж інформація про традиційний тип С, безумовно; це тип інформації, що кодує якусь семантичну деталь для позначення призначення об'єктів. Але це все ще інформація про тип, і правильним рішенням завжди було кодування її в системі типів. Кодування її до системи типів - це далеко не найкращий спосіб отримати належну перевірку та виконання правил. Назви змінних гірчиці просто не ріжуть.

Іншими словами, мета не повинна бути "зробити неправильний код невірним для розробника". Це повинно бути "зробити неправильний код невірним для компілятора ".


30
Намір змінної має бути закодовано в межах типу змінної, а не залишати щось таке крихке, як плачевна схема іменування.
DrPizza

3
Я б хотів зробити це також завданням компілятора / інтерпретатора, але це спричинило б великі накладні витрати на динамічні мови (Python, Ruby, PHP чи Javascript).
занадто багато php

22
"Однак, що більшості мов бракує, є типова система, достатньо виразна, щоб застосувати подібні відмінності". І в цьому полягає проблема. AppsHungarian - це прагматичний метод висвітлення проблем при використанні цих мов очевидними способами для програмістів, які переглядають код, а не вивчення звітів про помилки.
Ніл Тропден

6
@DrPizza: Я вважаю , що ви пропустили один з найважливіших моментів , які Джоел робить ратуючи Apps угорськи: цей запис просто дуже прагматичний компроміс . Зробити компілятор здатним бачити "неправильний код" - це велика мета, але чи завжди це варто його вартості?
Ярик

4
@DrPizza: Joel is wrongІ What most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.тому, оскільки більшості мов не вистачає виразності, щоб застосувати подібні відмінності, Джоел має рацію. Правильно?
sampathsris

46

Я думаю, що це масово захаращує вихідний код.

Він також не сильно набирає вас сильно набраною мовою. Якщо ви робите будь-яку форму типу невідповідності tomfoolery, компілятор розповість вам про це.


Ого. 90 повторів за 15 хвилин. Гарний дзвінок.
Дастман

2
Якщо ви використовуєте його для типу, то так, це марно. Корисно поширювати іншу інформацію.
Лу Франко

12
@Lou, точно - особисто я зберігаю історію редагування у своїх змінних імен: string firstName_wasName_wasNameID_wasSweetCupinCakes
Shog9,

@nsanders: Спробуйте використовувати компілятор, щоб перевірити, чи використовували ви однакові одиниці вимірювання, коли обидва типи змінних є цілими.
Ігор Левицький

1
@ Shog9: Я думаю, ви не зрозуміли угорську нотацію програм. Це більше про sFirstName vs unFirstName (безпечний проти небезпечний, несанізований), таким чином ви знаєте щось більше про це. І все-таки я думаю, що в статичних мовах краще для підтипу String зробити UnsafeString і SafeString і дозволити виводити SafeString. З конвенцією все нормально, але (частіше) виконання вимог щодо компіляції краще.
kgadek

28

Угорська позначення має сенс лише у мовах без визначених користувачем типів . У сучасній функціональній мові або OO-мові ви б кодували інформацію про "вид" значення в тип даних або клас, а не в назву змінної.

Кілька відповідей посилаються на статтю Джоелса . Зауважте, що його приклад є у VBScript, який не підтримував визначені користувачем класи (принаймні тривалий час). Мовою з визначеними користувачем типами ви вирішили б ту саму проблему, створивши тип HtmlEncodedString, а потім дозволив методу Write прийняти лише це. Статично набраною мовою компілятор вловлює будь-які помилки кодування, у динамічно набраному вигляді ви отримаєте виняток з виконання часу, але в будь-якому випадку ви захищені від написання некодованих рядків. Угорські позначення просто перетворюють програміста на перевірку типу людини, а саме таку роботу, як правило, краще обробляє програмне забезпечення.

Джоел розрізняє "угорський системний" і "угорський програми", де "угорський системний" кодує вбудовані типи, такі як int, float і так далі, і "угорський додаток" кодує "види", що є мета-інформацією вищого рівня про змінний beyound тип машини, В OO або сучасній функціональній мові ви можете створювати визначені користувачем типи, тому в цьому сенсі немає різниці між типом і "kind" - обидва можуть бути представлені системою типів - і "програмами" Угорська така ж зайва, як і угорська "системи".

Отже, щоб відповісти на ваше запитання: Система угорська була б корисною лише в небезпечній, слабо набраній мові, де, наприклад, присвоєння значення float змінної int призведе до краху системи. Угорська нотація була спеціально винайдена в шістдесятих роках для використання в BCPL , досить низькому рівні мови, яка взагалі не робила перевірки типу. Я не думаю, що будь-яка мова, яка сьогодні використовується загалом, має цю проблему, але позначення живуть як своєрідне культове програмування культу .

Угорські програми матимуть сенс, якщо ви працюєте з мовою без визначених користувачем типів, наприклад, застарілий VBScript або ранні версії VB. Можливо, також ранні версії Perl та PHP. Знову ж таки, використовувати його в сучасній мові - це чистий вантажний культ.

У будь-якій іншій мові угорська просто негарна, надмірна та тендітна. Він повторює інформацію, вже відому з типової системи, і ви не повинні повторювати себе . Використовуйте описову назву змінної, яка описує наміри цього конкретного екземпляра типу. Використовуйте систему типів для кодування інваріантів та метаінформації про "види" чи "класи" змінних - тобто. типи.

Загальний пункт статті Джоелса - неправильний код виглядає неправильним - дуже хороший принцип. Однак ще кращий захист від помилок - коли це можливо - мати неправильний код, який автоматично визначатиме компілятор.


Мови із визначеними користувачем типами не завжди дозволяють використовувати типи замість "види". Розгляньте префікси "c", "d", "ix" з програми Joel's Apps Hungarian. Чи використовуєте ви цільові цілі типи для цих сучасних мов усіма сучасними мовами? Я не думаю, що так. Оскільки в сучасних мовах досі немає вбудованих спеціальних цілих типів для індексів, підрахунків та відмінностей між двома числами. Поки ми все ще використовуємо ванільні вкладиші, угорські програми не будуть зайвими та корисними.
Eldritch Conundrum

27

Я завжди використовую угорські позначення для всіх своїх проектів. Я вважаю це дуже корисним, коли я маю справу зі 100 іменами різних імен ідентифікаторів.

Наприклад, коли я викликаю функцію, що вимагає рядка, я можу набрати 's' і натиснути на простір управління, і мій IDE покаже мені саме імена змінних з префіксом 's'.

Ще одна перевага, коли я встановлюю префікс u для непідписаного та i для підписаних ints, я одразу бачу, де я змішую підписані та неподписані потенційно небезпечні способи.

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

Це питання смаку та досвіду. Не стукайте, поки ви не спробували.


1
Кодування підпису в імена змінних чудово, коли фрагмент коду насправді має справу з підписанням. Використовувати це як привід для виконання конвенції для всіх змінних є просто доматизм IMHO.
Плюменатор

Ти маєш гарну точку з змінними членами. Але в таких мовах, як Python, де ви змушені кваліфікувати членів себе / цього об'єкта, це суперечка.
Плуменатор

Це просто хитрість, щоб підвищити продуктивність. Так само, як IDE автозаповнення. У цьому немає нічого принципово зла. Я вважаю, що досвідченим кодерам потрібно дозволити використовувати власний стиль. Примушувати когось обрати певний стиль - це погано. Зараз я працюю як окремий розробник, але я б не нав'язував стилю нікому, з ким працював, якщо б їм не вистачало послідовного стилю в першу чергу.
rep_movsd

Отже, ви використовуєте конвенцію про іменування для фільтрації змінних, так? Я повинен погодитися, що це якось розумно . :-) Однак те, як мене проводять, точка прив’язки (або критерій фільтра, якщо вам подобається) - це для мене завжди семантика. Рідко тип (якщо це не семантичний). Сподіваюся, це мало сенс. TL; DR: Я все-таки дотримуюся іменування змінних відповідно до того, що вони представляють, ніж того, як вони представлені.
Плюменатор

1
Тоді я підтримав це ще з тих пір, оскільки виступав за угорську. Тепер я шкодую про це, і ніколи не повернусь до префіксації чогось змінної ..
nawfal

22

Ви забуваєте причину номер один, щоб включити цю інформацію. Це не має нічого спільного з вами, програміст. Це має відношення до того, що людина виїжджає на дорогу через 2 або 3 роки після того, як ви покинете компанію, яка має читати ці речі.

Так, IDE швидко визначить типи для вас. Однак, коли ви читаєте кілька довгих пакетів коду «бізнес-правил», непогано не робити пауз на кожній змінній, щоб дізнатися, що це за тип. Коли я бачу такі речі, як strUserID, intProduct або guiProductID, це значно полегшує час «нарощування».

Я погоджуюся з тим, що МС зайшла занадто далеко з деякими їх умовами іменування - я класифікую це в купі "занадто багато хорошого".

Конвенції про іменування - це хороші речі, якщо ви їх дотримуєтесь. Я пережив досить старий код, який змусив мене постійно повертатися назад, щоб подивитися на визначення для такої кількості змінних аналогічним чином, що я натискаю "кожух верблюда" (як його називали на попередній роботі). Зараз я на роботі, яка містить багато тисяч рядків абсолютно некомментованого класичного коду ASP з VBScript, і це кошмар, який намагається з'ясувати речі.


Як користувач VIM (без IDE, без підсвічування, без наведення курсора-скажіть, який тип), я взагалі не розумію цей аргумент. Я природно розумію, що змінна, що називається ім'ям, являє собою рядок, а змінна під назвою i або count - це int. Чи справді потрібні sName та iCount? Як це насправді допомагає? Я заперечую, що ваш приклад ідентифікатора продукту - це особливий випадок, і, можливо, там це було б добре. Але навіть тоді, бути послідовним і представляти ідентифікатори продукту з вбудованими або рядками скрізь, було б набагато кращим рішенням, ні? Уся річ з іменуванням здається копіювачем.
MrFox

6
Це для послідовності. Так, "ім'я" по суті означає рядок. Але яким би ти вважав "userid"? Керівництво? Рядок? Цілий? Навіть щось на кшталт "acctno" може мати значення 42 або "23X". Документація в більшості кодів є достатньо рідкою. Цей стандарт трохи допомагає програмісту з технічного обслуговування.
Девід

1
@David Я абсолютно згоден з вашою відповіддю - знаючи з першого погляду намір змінної є причиною, чому я віддаю перевагу також префіксам, тим більше в динамічній мові, як JS.
Даніель Соколовський

10

Використання криптовалютних символів на початку кожної назви змінної непотрібне, і це показує, що ім'я змінної саме по собі недостатньо описове. Більшість мов так чи інакше потребують типу змінної при декларації, так що інформація вже доступна.

Існує також ситуація, коли під час технічного обслуговування потрібно змінювати тип змінної. Приклад: якщо змінна, оголошена "uint_16 u16foo", повинна стати 64-бітовою без підпису, відбудеться одна з двох речей:

  1. Ви перейдете та зміните кожну назву змінної (не переконуючись в шлангу жодних непов'язаних змінних з тим самим іменем), або
  2. Просто змініть тип і не змінюйте ім’я, що лише спричинить плутанину.

9

Джоел Спольський написав про це хороший пост у блозі. http://www.joelonsoftware.com/articles/Wrong.html В основному це зводиться до того, щоб не ускладнювати читання вашого коду, коли гідний IDE скаже, що ви хочете ввести змінну, якщо ви не можете згадати. Крім того, якщо ви зробите свій код досить розділеним, вам не доведеться пам'ятати, яка змінна була оголошена як три сторінки вгору.


9

Не є сфера важливіша, ніж тип в наші дні, наприклад

* l for local
* a for argument
* m for member
* g for global
* etc

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


Знову ж таки, код, мабуть, не повинен так сильно залежати від обсягу. :-)
Плюменатор

8

Немає жодної причини, чому ви не повинні правильно використовувати угорські позначення. Його непопулярність пояснюється тривалим зворотним ударом проти неправильного використання угорської нотації, особливо в API Windows.

У погані старі часи, перш ніж для DOS існувало щось, що нагадувало IDE (шанси на те, що у вас не вистачало вільної пам’яті для запуску компілятора під Windows, тому ваша розробка робилася в DOS), ви не отримали жодної допомоги від наведення миші на ім’я змінної. (Якщо припустити, що у вас є миша.) Що з чим вам довелося мати справу - це функції зворотного виклику подій, в яких все передається вам як 16-бітний int (WORD) або 32-бітний int (LONG WORD). Тоді вам довелося привести ці параметри до відповідних типів для даного типу події. Насправді, більша частина API практично не відрізнялася від типу.

Результат, API з назвами параметрів, таких як:

LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT uMsg,
                            WPARAM wParam,
                            LPARAM lParam);

Зауважте, що імена wParam і lParam, хоча і досить жахливі, насправді не гірші, ніж називати їх param1 та param2.

Що ще гірше, Window 3.0 / 3.1 мав два типи покажчиків - поблизу та далеко. Так, наприклад, повернене значення з функції управління пам'яттю LocalLock було PVOID, але повернене значення від GlobalLock було LPVOID (з 'L' протягом тривалого часу). Це жахливо нотація тоді розширилися , так що L Ong р ointer рядки був приставка LP , щоб відрізнити його від рядка, були просто malloc'd.

Не дивно, що проти подібних речей відбувся зворотний ефект.


6

Угорська нотація може бути корисною мовами без перевірки часу компіляції, оскільки це дозволить розробнику швидко нагадати про те, як використовується певна змінна. Це нічого не робить для продуктивності чи поведінки. Він повинен покращити читабельність коду, і це, головним чином, питання смаку та стилю кодування. Саме тому багато розробників піддаються критиці - не у всіх однакова проводка в мозку.

Для мов перевірки типів часу компіляції це здебільшого марно - прокручування декількох рядків повинно виявити декларацію і таким чином ввести. Якщо у вас глобальні змінні або блок коду охоплює набагато більше одного екрана, у вас є серйозні проблеми із дизайном та повторним використанням. Таким чином, одна з закидів полягає в тому, що угорська нотація дозволяє розробникам мати поганий дизайн і легко піти з ним. Мабуть, це одна з причин ненависті.

З іншого боку, можуть бути випадки, коли навіть мови перевірки типу компіляції виграють від угорської нотації - недійсних покажчиків або HANDLE в API Win32. Вони обтяжують фактичний тип даних, і можливо, в цьому є використання угорської нотації. Тим не менш, якщо можна знати тип даних під час збирання, чому б не використовувати відповідний тип даних.

Загалом, немає важких причин не використовувати угорські позначення. Це питання лайків, політики та стилю кодування.


6

Як програміст Python, угорська нотація розпадається досить швидко. У Python мені байдуже, чи щось є рядком - мені байдуже, чи може він діяти як рядок (тобто, якщо у нього є ___str___()метод, який повертає рядок).

Наприклад, скажімо, що у нас є foo як ціле число, 12

foo = 12

Угорська нотація говорить нам, що ми повинні називати це iFoo або щось таке, щоб позначити це ціле число, щоб згодом ми дізналися, що це таке. За винятком Python, це не працює, точніше, це не має сенсу. У Python я вирішую, який тип я хочу, коли його використовую. Я хочу рядок? добре, якщо я роблю щось подібне:

print "The current value of foo is %s" % foo

Зверніть увагу на %sрядок -. Foo не є рядком, але %оператор зателефонує foo.___str___()та використає результат (припустивши, що він існує). fooвсе ще ціле число, але ми трактуємо це як рядок, якщо хочемо рядок. Якщо ми хочемо поплавок, то ми ставимося до нього як до поплавця. У динамічно набраних мовах, таких як Python, угорська нотація є безглуздою, оскільки не має значення, що таке щось, поки ви не користуєтесь ним, а якщо вам потрібен певний тип, то просто переконайтеся, що float(foo)ви перейдете до цього типу (наприклад ), коли ви використай це.

Зауважте, що такі динамічні мови, як PHP, не користуються цією перевагою - PHP намагається зробити "правильну справу" на задньому плані на основі неясного набору правил, які майже ніхто не запам'ятовував, що часто призводить до катастрофічних помилок несподівано. У цьому випадку якийсь механізм іменування, як-от $files_countабо $file_name, може бути корисним.

На мою думку, угорська нотація - це як п'явки. Можливо, раніше вони були корисними або, принаймні, здавалися корисними, але в наш час це просто багато зайвого набору тексту для не дуже великої користі.


Цікаво, що ваш приклад з .str () в Python не є результатом того, що мова є динамічною. Java, безумовно, не динамічна мова, робить те саме.
Дастман

C # також робить те ж саме, кожен клас мовою реалізує .ToString()так, щоб це все можна було надрукувати
Electric Coffee

5

IDE повинен передавати цю корисну інформацію. Угорська могла мати певний сенс (не цілу партію, але якийсь) сенсу, коли IDE були набагато менш розвиненими.


4
Потім знову не слід покладатися на те, що IDE розповість вам більше. Зрештою, код можна переглянути за межами IDE ...
TraumaPony,

5

Програми Угорська для мене грецька - в хороший спосіб

Як інженер, а не програміст, я негайно перейшов до статті Джоела про заслуги угорської програми: "Зробити неправильний код виглядати невірно" . Мені подобаються програми угорської мови, тому що вона імітує те, як інженерія, наука та математика представляють рівняння та формули, використовуючи символи суб- та надрукованого сценарію (наприклад, грецькі літери, математичні оператори тощо). Візьмемо конкретний приклад Закону про загальну гравітацію Ньютона : спочатку у стандартній математичній нотації, а потім у псевдокодексі Угорщини:

Універсальний закон тяжіння Ньютона для Землі та Марса

frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)

У математичних позначеннях найвизначнішими символами є символи, що представляють вид інформації, що зберігається у змінній: сила, маса, вектор положення тощо. Підписники відтворюють другу загадку для уточнення: положення чого? Саме цим займаються програми угорської мови; він говорить вам вид речі , що зберігається в змінної першої , а потім отримати в специфіку - близько найближчого коду можна отримати в математичній нотації.

Очевидно, що сильне введення тексту може вирішити приклад безпечного та небезпечного рядка з нарису Джоеля, але ви не визначали б окремі типи для векторів позиції та швидкості; обидва - це подвійні масиви розміром три, і все, що ви, ймовірно, зробите для одного, може застосувати до іншого. Крім того, має сенс об'єднати положення і швидкість (зробити вектор стану) або взяти їх точковий продукт, але, ймовірно, не додавати їх. Як типізація дозволить першим двом і заборонити другу, і як подібна система пошириться на всі можливі операції, які ви хочете захистити? Якщо ви не готові були закодувати всю математику та фізику у своїй машинописній системі.

Крім того, багато інженерних робіт робиться на слабо типізованих мовах високого рівня, таких як Matlab, або старих, таких як Fortran 77 або Ada.

Тож якщо ви володієте модною мовою, а IDE та програми угорською не допомагають, то забудьте про це - мабуть, багато людей. Але для мене, гірше, ніж початківець програміст, який працює слабко або динамічно набраними мовами, я можу краще писати код швидше за допомогою угорської програми, ніж без.


4

Це неймовірно зайві та марні більшість сучасних ІДЕ, де вони роблять хорошу роботу, роблячи тип очевидним.

Плюс - мені - просто прикро бачити intI, strUserName тощо. :)


3
Як розповів TraumaPony Пол Батум, не всі бачать код в IDE.
Кріс Чарабарук

4

Якщо я відчуваю, що корисна інформація передається, чому б я не ставлю її там, де вона є?

Тоді кого байдуже, що ще хтось думає? Якщо вам це здається корисним, тоді використовуйте позначення.


Тому що є лише один із мене і мільярд інших людей, які згодом можуть підтримувати мій код. Оскільки всі ці люди в команді (але вони цього ще не знають), я хотів би мати деяке уявлення, якщо вони переможуть мене.
Дастман

4

Я мій досвід, це погано, оскільки:

1 - тоді ви порушуєте весь код, якщо вам потрібно змінити тип змінної (тобто якщо вам потрібно розширити 32-бітове ціле число до цілого 64 біта);

2 - це марна інформація, оскільки тип або вже є в декларації, або ви використовуєте динамічну мову, де власне тип не повинен бути таким важливим в першу чергу.

Більше того, з мовою, яка приймає загальне програмування (тобто функції, де тип деяких змінних не визначається під час написання функції) або з динамічною системою набору тексту (тобто коли тип навіть не визначається під час компіляції), як би ви назвали свій змінні? І більшість сучасних мов підтримують ту чи іншу, навіть якщо це обмежена форма.


4

У статті Джоела Спольського "Створення помилкового коду виглядають неправильно" він пояснює, що те, що всі вважають угорською нотацією (яку він називає системою Угорська), - це не те, що було насправді (як він називає Apps Hungarian). Прокрутіть униз до заголовка Я Угорщина, щоб переглянути цю дискусію.

В основному, Система Угорська нічим не потрібна. Це просто говорить вам те саме, що вам скаже ваш компілятор та / або IDE.

Програми угорської мови розповідають про те, що повинна означати змінна та може бути корисною.


4

Я завжди думав, що префікс-два в потрібному місці не зашкодить. Я думаю, що якщо я можу надати щось корисне, як-от "Ей, це інтерфейс, не розраховуйте на конкретну поведінку" саме там, як в IEnumerable, я повинен зробити це. Коментар може захаращувати речі набагато більше, ніж просто символ одного чи двох символів.


1
Я ніколи не отримував ІНТИЧОГО. Якщо це -able, це все одно має на увазі інтерфейс. (Принаймні, у java)
тунаранч

4

Це корисна умова для іменування елементів керування у формі (btnOK, txtLastName тощо), якщо список елементів керування відображається в алфавітному спадному списку у вашому IDE.


4

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

Візьміть цей фрагмент коду:

<asp:Label ID="lblFirstName" runat="server" Text="First Name" />
<asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ... />

Якщо хтось може показати кращий спосіб мати цей набір контрольних імен без угорської, я б спокусився перейти до нього.


4

Стаття Джоеля чудова, але, здається, вона пропустила один головний момент:

Угорська робить певну «ідею» (назви + ім’я ідентифікатора) унікальною або майже унікальною для всієї кодової бази - навіть дуже великої бази коду.

Це величезне обслуговування коду. Це означає, що ви можете використовувати хороший однорядковий пошук тексту (grep, findstr, "знайти у всіх файлах"), щоб знайти КОЖНУ згадку про цю "ідею".

Чому це важливо, коли у нас є IDE, які вміють читати код? Тому що вони ще не дуже добре в цьому. Це важко помітити у невеликій кодовій базі, але очевидною у великій - коли «ідея» може бути згадана у коментарях, XML-файлах, скриптах Perl, а також у місцях, що знаходяться поза джерелом контролю (документи, вікі, бази помилок).

Ви повинні бути трохи обережними навіть тут - наприклад, вставка лексеми в макросах C / C ++ може приховати згадки про ідентифікатор. Такі випадки можна вирішувати з використанням умов кодування, і в будь-якому випадку вони, як правило, зачіпають лише меншість ідентифікаторів у кодовій базі.

PS Що стосується використання типової системи проти угорської - краще використовувати обидва. Вам потрібен неправильний код, щоб виглядати неправильно, якщо компілятор не знайде його за вас. Існує маса випадків, коли компілятор не може змусити його зловити. Але де це можливо - так, будь ласка, зробіть це замість цього!

Однак, розглядаючи можливість, врахуйте негативні наслідки розщеплення типів. наприклад, у C #, загортання "int" з не вбудованим типом має величезні наслідки. Тож це має сенс у деяких ситуаціях, але не у всіх.


4

Розблокування переваг угорської нотації

  • Він забезпечує спосіб розрізнення змінних.

Якщо тип - це все, що відрізняє одне значення від іншого, то це може бути лише для перетворення одного типу в інший. Якщо у вас є одне і те ж значення, яке перетворюється між типами, швидше за все, ви повинні це зробити у функції, призначеної для перетворення. (Я бачив, що залишені VB6 з угорщиною використовують рядки для всіх своїх параметрів методу просто тому, що вони не могли зрозуміти, як деріаріалізувати об'єкт JSON, або правильно зрозуміти, як оголосити або використовувати нульові типи. ) Якщо у вас є дві змінні, що відрізняються лише за Угорський префікс, і вони не є перетворенням одного в інший, тоді вам потрібно детальніше розібратися зі своїм наміром.

  • Це робить код більш читабельним.

Я виявив, що угорська нотація змушує людей лінуватися своїми змінними іменами. У них є чим відрізняти це, і вони не відчувають потреби уточнювати його мету. Це те, що ви зазвичай знайдете в угорському позначеному кодом порівняно з сучасним: sSQL vs. groupSelectSql ( або зазвичай взагалі немає sSQL, оскільки вони, як передбачається, використовують ORM, який були застосовані попередніми розробниками. ), SValue vs. formCollectionValue ( або, як правило, також немає sValue, оскільки вони трапляються в MVC і повинні використовувати його функції прив'язки моделі ), sType порівняно з pubSource тощо.

Це не може бути читабельність. Я бачу більше sTemp1, sTemp2 ... sTempN від будь-якого даного залишеного VB6, ніж у всіх інших.

  • Це запобігає помилкам.

Це було б в силу числа 2, що є помилковим.


3

Словами майстра:

http://www.joelonsoftware.com/articles/Wrong.html

Цікаве читання, як завжди.

Виписки:

"Хтось десь читав папери Симоні, де він вживав слово" тип ", і думав, що він означає тип, як клас, як у типовій системі, як перевірка типу, що робить компілятор. Він цього не зробив. Він дуже ретельно пояснив саме те, що він мав на увазі під словом "тип", але це не допомогло. Шкода була заподіяна ".

"Але для Угорської програми все ще є величезна цінність, оскільки вона збільшує колокацію в коді, що полегшує код для читання, запису, налагодження та обслуговування, і, що найголовніше, він робить неправильний код невірним."

Переконайтесь, що у вас є деякий час, перш ніж читати Joel On Software. :)


Немає часу, коли у мене є Stackoverflow. Я думаю, що це має бути лише асоціація Спольського з проектом. :)
Дастман

3

Кілька причин:

  • Будь-який сучасний IDE надасть вам тип змінної, просто навести курсор миші на змінну.
  • Більшість імен типів є досить довгими (думаю, що HttpClientRequestProvider ) розумно використовуються як префікс
  • Інформація про тип не несе потрібної інформації, вона просто перефразовує декларацію змінної, а не окреслює мету змінної (подумайте, myInteger vs. pageSize ).

2

Я не думаю, що всі жорстоко проти цього. Мови без статичних типів досить корисні. Я, безумовно, віддаю перевагу, коли він використовується для надання інформації, яка вже не входить у тип. Як і в C, char * szName говорить, що змінна буде посилатися на нульовий завершений рядок - це не неявно в char * - звичайно, typedef також допоможе.

У Джоела була чудова стаття про використання угорської мови, щоб сказати, чи змінна кодована HTML чи ні:

http://www.joelonsoftware.com/articles/Wrong.html

У всякому разі, я схильний не любити угорську мову, коли вона використовується для передачі інформації, яку я вже знаю.


Я думаю, що перше речення може повірити на відповіді на цій сторінці.
Дастман

@Dustman Ну, ти вже не знаєш, що рядки C недійсні? Я бачу, як це було б корисно, коли рядок може бути не так, але це рідко, тому я вважаю, що використання конвенції має обмежуватися лише тими випадками.
Плуменатор

Не кожен char * є нульовим завершеним рядком c. Сенс угорської полягає в тому, щоб використовувати його для кожної змінної, навіть тієї, що потрапляє до загального випадку. Зрештою, я відчуваю себе так само, як і ти, і тому я не використовую це в C.
Лу Франко

2

Звичайно, коли 99% програмістів погоджуються на щось, відбувається щось не так. Причина, з якою вони погоджуються тут, полягає в тому, що більшість з них ніколи не використовували правильно угорські позначення правильно.

Для детального аргументу я посилаю вас на повідомлення в блозі, яке я зробив з цього приводу.

http://codingthriller.blogspot.com/2007/11/rediscovering-hungarian-notation.html


2

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

Через деякий час я зрозумів, що коли це було зроблено належним чином, це насправді допомагає, і в наші дні я це люблю.

Але, як і все добре, це потрібно вивчити і зрозуміти, і щоб це зробити належним чином, потрібен час.


1

Угорські позначення зловживають, зокрема, Microsoft, що призводить до префіксів, довших за назву змінної, і показує, що вони досить жорсткі, особливо коли ви змінюєте типи (сумнозвісний lparam / wparam, іншого типу / розміру в Win16, ідентичний у Win32 ).

Таким чином, як через це зловживання, так і його використання M $, воно було визнано марним.

На моїй роботі ми кодуємо Java, але засновник називає кеш-пам'ять зі світу MFC, тому використовуємо аналогічний стиль коду (вирівнювані дужки, мені це подобається !, великі літери до методів імен, я звик до цього, префікс, як m_ членам класу ), s_ до статичних членів тощо).

І вони сказали, що всі змінні повинні мати префікс, що показує його тип (наприклад, BufferedReader називається brData). Це показано як погана ідея, оскільки типи можуть змінюватись, але назви не випливають, або кодери не несумісні у використанні цих префіксів (я навіть бачу aBuffer, theProxy тощо)!

Особисто я вибрав кілька префіксів, які мені здаються корисними, найважливішим є b для префікса булевих змінних, оскільки вони є єдиними, де я допускаю синтаксис, як if (bVar)(немає використання автоматичної передачі деяких значень на істинне чи хибне). Коли я кодував C, я використовував префікс для змінних, виділених malloc, як нагадування, його слід звільнити пізніше. І т.д.

Отже, я взагалі не відкидаю це позначення в цілому, але прийняв те, що здається, що відповідає моїм потребам.
І звичайно, коли я беру участь у якомусь проекті (роботі, відкритому коді), я просто використовую умовні умови!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.