Я все в пользу префиксов, сделанных хорошо .
Я думаю (Системная) Венгерская нотация ответственна за большую часть "плохого рэпа", который получают префиксы.
Это обозначение в значительной степени бессмысленно в строго типизированных языках, например в C ++ "lpsz", чтобы сказать вам, что ваша строка является длинным указателем на строку с нулевым символом в конце, когда: сегментированная архитектура - древняя история, строки C ++ по общему соглашению являются указателями на массив символов с нулевым символом в конце, и это не так уж сложно знать, что "customerName" - это строка!
Однако я использую префиксы для указания использования переменной (по сути, «Apps Hungarian», хотя я предпочитаю избегать термина венгерский из-за плохой и несправедливой ассоциации с System Hungarian) и это очень удобный способ экономии и уменьшения ошибок .
Я использую:
- м для членов
- c для констант / только для чтения
- p для указателя (и pp для указателя на указатель)
- V для летучих
- с для статического
- i для индексов и итераторов
- e для событий
Там, где я хочу сделать тип понятным, я использую стандартные суффиксы (например, List, ComboBox и т. Д.).
Это позволяет программисту знать о использовании переменной всякий раз, когда он видит / использует ее. Возможно, наиболее важным случаем является «p» для указателя (потому что использование меняется с var. На var-> и вам нужно быть намного осторожнее с указателями - NULL, арифметикой указателей и т. Д.), Но все остальные очень удобны.
Например, вы можете использовать одно и то же имя переменной несколькими способами в одной функции: (здесь пример C ++, но он в равной степени применим ко многим языкам)
MyClass::MyClass(int numItems)
{
mNumItems = numItems;
for (int iItem = 0; iItem < mNumItems; iItem++)
{
Item *pItem = new Item();
itemList[iItem] = pItem;
}
}
Вы можете увидеть здесь:
- Нет путаницы между элементом и параметром
- Нет путаницы между индексом / итератором и элементами
- Использование набора четко связанных переменных (список элементов, указатель и индекс), которые позволяют избежать многих ловушек общих (расплывчатых) имен, таких как "count", "index".
- Префиксы уменьшают набор текста (короче, и работают лучше с автозаполнением), чем альтернативы, такие как "itemIndex" и "itemPtr"
Еще одним замечательным моментом итераторов iName является то, что я никогда не индексирую массив с неверным индексом, и если я копирую цикл внутри другого цикла, мне не нужно реорганизовывать одну из переменных индекса цикла.
Сравните этот нереально простой пример:
for (int i = 0; i < 100; i++)
for (int j = 0; j < 5; j++)
list[i].score += other[j].score;
(который трудно читать и часто приводит к использованию «i» там, где «j» предназначался)
с:
for (int iCompany = 0; iCompany < numCompanies; iCompany++)
for (int iUser = 0; iUser < numUsers; iUser++)
companyList[iCompany].score += userList[iUser].score;
(что намного удобочитаемее и устраняет путаницу при индексировании. С автозаполнением в современных IDE это также быстро и легко вводится)
Следующим преимуществом является то, что фрагменты кода не требуют понимания контекста . Я могу скопировать две строки кода в электронное письмо или документ, и любой, кто читает этот фрагмент, может заметить разницу между всеми членами, константами, указателями, индексами и т. Д. Мне не нужно добавлять «о, и будьте осторожны, потому что «data» - это указатель на указатель », потому что он называется« ppData ».
И по той же причине мне не нужно отводить взгляд от строки кода, чтобы понять это. Мне не нужно искать в коде, чтобы определить, является ли «data» локальным, параметром, членом или константой. Мне не нужно подносить руку к мыши, чтобы я мог навести указатель мыши на «данные», а затем дождаться всплывающей подсказки (которая иногда не появляется). Таким образом, программисты могут читать и понимать код значительно быстрее, потому что они не тратят время на поиск вверх и вниз или ожидание.
(Если вы не думаете, что тратите время на поиски и поиски вещей, найдите код, который вы написали год назад и на который не смотрели
поскольку. Откройте файл и прыгайте на полпути вниз, не читая его.
Посмотрите, как далеко вы можете читать с этого момента, прежде чем вы не знаете, есличто-то является членом, параметром или локальным. Теперь перейдите к другому случайному
местоположение ... Это то, что мы все делаем целый день, когда мы одиноки
перебирая чужой код или пытаясь понять, как
вызовите их функцию)
Префикс 'm' также позволяет избежать (ИМХО) уродливой и многословной нотации "this->" и несоответствия, которое он гарантирует (даже если вы будете осторожны, у вас, как правило, будет смесь 'this-> data 'и' data 'в одном классе, потому что ничто не обеспечивает согласованное написание имени).
эта «нотация» предназначена для разрешения неоднозначности - но зачем кому-то сознательно писать код, который может быть неоднозначным? Неоднозначность рано или поздно приведет к ошибке 1089. А в некоторых языках «this» нельзя использовать для статических членов, поэтому вам нужно ввести «особые случаи» в свой стиль кодирования. Я предпочитаю иметь одно простое правило кодирования, которое применяется везде - явное, однозначное и последовательное.
Последнее главное преимущество - Intellisense и автозаполнение. Попробуйте использовать Intellisense в форме Windows для поиска события - вам нужно прокрутить сотни таинственных методов базового класса, которые вам никогда не понадобятся для поиска событий. Но если бы у каждого события был префикс «e», они были бы автоматически перечислены в группе под «e». Таким образом, префикс работает для группировки членов, констант, событий и т. Д. В списке intellisense, что позволяет гораздо быстрее и проще находить нужные имена. (Обычно метод может иметь около 20-50 значений (локальные, параметры, члены, константы, события), которые доступны в его области. Но после ввода префикса (я хочу использовать индекс сейчас, поэтому я набираю 'i. .. '), у меня есть только 2-5 опций автозаполнения. Атрибуты "дополнительная типизация", приписываемые префиксам и осмысленным именам, значительно сокращают пространство поиска и заметно увеличивают скорость разработки)
Я ленивый программист, и вышеприведенное соглашение спасает мне много работы. Я могу писать быстрее и совершать гораздо меньше ошибок, потому что знаю, как использовать каждую переменную.
Аргументы против
Итак, каковы минусы? Типичные аргументы против префиксов:
«Префиксные схемы плохие / злые» . Я согласен с тем, что «m_lpsz» и тому подобное плохо продуманы и совершенно бесполезны. Вот почему я бы посоветовал использовать хорошо разработанную нотацию, разработанную для поддержки ваших требований, а не копировать что-то, что не подходит для вашего контекста. (Используйте правильный инструмент для работы).
«Если я изменяю использование чего-либо, я должен переименовать его» * 1112 *. Да, конечно, вы понимаете, вот что такое рефакторинг, и почему в IDE есть инструменты рефакторинга, чтобы выполнять эту работу быстро и безболезненно. Даже без префиксов изменение использования переменной почти наверняка означает, что ее имя должно быть изменено.
«Префиксы меня просто смущают» . Как и каждый инструмент, пока вы не научитесь его использовать. Как только ваш мозг привыкнет к шаблонам именования, он автоматически отфильтрует информацию, и вы не будете возражать, что префиксы уже есть. Но вы должны использовать такую схему в течение недели или двух, прежде чем вы действительно станете "свободно". И вот тогда многие люди смотрят на старый код и начинают задумываться, как им удавалось без хорошей схемы префиксов.
«Я могу просто посмотреть на код, чтобы разобраться с этим» . Да, но вам не нужно тратить время на поиск других частей кода или запоминание каждой мелочи, когда ответ прямо на месте, на котором уже сфокусирован ваш глаз.
(некоторая часть) эту информацию можно найти, просто подождав всплывающей подсказки для моей переменной . Да. Там, где это поддерживается, для некоторых типов префиксов, когда ваш код правильно компилируется, после ожидания вы можете прочитать описание и найти информацию, которую префикс передал бы мгновенно. Я чувствую, что префикс - это более простой, надежный и эффективный подход.
"Это больше печатать" . В самом деле? Еще один целый персонаж? Или это так - с помощью инструментов автозаполнения IDE это часто сокращает ввод текста, поскольку каждый префиксный символ значительно сужает пространство поиска. Нажмите «e», и три события в вашем классе всплывают в intellisense. Нажмите «c», и пять констант будут перечислены.
«Я могу использовать this->
вместо m
» . Ну, да, вы можете. Но это просто более уродливый и более подробный префикс! Только он несет гораздо больший риск (особенно в командах), потому что для компилятора это необязательно , и поэтому его использование часто противоречиво. m
, с другой стороны, является кратким, ясным, явным и необязательным, поэтому намного труднее делать ошибки при его использовании.