Я все в пользу префиксов сделано хорошо .
Я думаю (Системная) Венгерская нотация ответственна за большую часть "плохого рэпа", который получают префиксы.
Эта нотация в языках со строгой типизацией в значительной степени бессмысленна, например, в «lpsz» C ++, чтобы сказать вам, что ваша строка является длинным указателем на строку с нулевым окончанием, когда: сегментированная архитектура - древняя история, строки C ++ по общему соглашению являются указателями на нуль-завершенные массив символов, и на самом деле не так уж и сложно понять, что customerName - это строка!
Тем не менее, я использую префиксы для указания использования переменной (по сути, «венгерский приложения», хотя я предпочитаю избегать термина венгерский из-за его плохой и несправедливой ассоциации с венгерским системой), и это очень удобно и экономит время метод устранения ошибок .
Я использую:
- м для членов
- c для констант / только для чтения
- p для указателя (и pp для указателя на указатель)
- V для летучих
- с для статического
- я для индексов и итераторов
- е для событий
Там, где я хочу прояснить тип , я использую стандартные суффиксы (например, 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» также позволяет избежать (IMHO) уродливой и многословной нотации «this->» и несогласованности, которую он гарантирует (даже если вы будете осторожны, вы, как правило, в конечном итоге получите смесь «this-> data» и 'data' в том же классе, потому что ничто не обеспечивает согласованное написание имени).
Эта нотация предназначена для устранения неоднозначности, но зачем кому-то сознательно писать код, который может быть неоднозначным? Неоднозначность будет приводить к ошибке , рано или поздно. А в некоторых языках «this» нельзя использовать для статических элементов, поэтому вам нужно ввести «особые случаи» в свой стиль кодирования. Я предпочитаю иметь одно простое правило кодирования, которое применяется везде - явное, однозначное и последовательное.
Последнее главное преимущество - Intellisense и автозаполнение. Попробуйте использовать Intellisense в форме Windows, чтобы найти событие - вам нужно пролистать сотни таинственных методов базового класса, которые вам никогда не понадобятся для поиска событий. Но если бы у каждого события был префикс «e», они автоматически были бы перечислены в группе под «e». Таким образом, префикс работает для группировки членов, констант, событий и т. Д. В списке intellisense, что позволяет гораздо быстрее и проще находить нужные имена. (Обычно метод может иметь около 20-50 значений (локальные, параметры, члены, константы, события), которые доступны в его области. Но после ввода префикса (я хочу использовать индекс сейчас, поэтому я набираю 'i. .. '), у меня есть только 2-5 вариантов автозаполнения.
Я ленивый программист, и вышеуказанное соглашение спасает мне много работы. Я могу кодировать быстрее и делаю гораздо меньше ошибок, потому что знаю, как использовать каждую переменную.
Аргументы против
Итак, каковы минусы? Типичные аргументы против префиксов:
«Префиксные схемы плохие / злые» . Я согласен с тем, что «m_lpsz» и тому подобное плохо продуманы и совершенно бесполезны. Вот почему я бы посоветовал использовать хорошо разработанную нотацию, разработанную для поддержки ваших требований, а не копировать то, что не подходит для вашего контекста. (Используйте правильный инструмент для работы).
«Если я изменю использование чего-либо, я должен переименовать его» . Да, конечно, вы понимаете, вот что такое рефакторинг, и почему в IDE есть инструменты рефакторинга, которые позволяют выполнять эту работу быстро и безболезненно. Даже без префиксов изменение использования переменной почти наверняка означает, что ее имя следует изменить.
«Приставки меня просто смущают» . Как и каждый инструмент, пока вы не научитесь его использовать. Как только ваш мозг привыкнет к шаблонам именования, он автоматически отфильтрует информацию, и вы не будете возражать, что префиксы уже есть. Но вы должны использовать такую схему твердо в течение недели или двух, прежде чем вы действительно станете "свободно". И именно тогда многие люди смотрят на старый код и начинают задумываться, как им вообще удавалось обходиться без хорошей префиксной схемы.
«Я могу просто посмотреть на код, чтобы разобраться с этим» . Да, но вам не нужно тратить время на поиски в другом месте кода или запоминания каждой мелочи, когда ответ прямо на месте, на котором ваш глаз уже сфокусирован.
(Некоторые из) этой информации можно найти, просто подождав, пока всплывающая подсказка появится в моей переменной . Да. Там, где это поддерживается, для некоторых типов префиксов, когда ваш код корректно компилируется, после ожидания вы можете прочитать описание и найти информацию, которую префикс передал бы мгновенно. Я чувствую, что префикс - это более простой, надежный и эффективный подход.
«Это больше печатать» . В самом деле? Еще один целый персонаж? Или это так - с помощью инструментов автозаполнения IDE это часто сокращает набор текста, поскольку каждый префиксный символ значительно сужает пространство поиска. Нажмите «e», и три события в вашем классе всплывают в intellisense. Нажмите «с» и пять констант перечислены.
«Я могу использовать this->
вместо m
» . Ну, да, вы можете. Но это просто более уродливый и многословный префикс! Только он несет гораздо больший риск (особенно в командах), потому что для компилятора это не обязательно , и поэтому его использование часто противоречиво. m
с другой стороны, это кратко, ясно, явно и не является обязательным, поэтому намного труднее делать ошибки, используя его.