Совершенный код

грамотностьЧто бы в будущем не прибегать к рефакторингу к переписыванию ужасающего кода, писать код нужно грамотно. Что такое грамотно написанный код? То же самое, что и грамотно написанный текст, написанный "согласно установленным нормам грамматики и правописания".

Основная проблема русскоязычных программистов в том, что они пишут программы не на родном языке. Тривиальные англоязычные слова типа "page", "id", "start", "limit" усваиваются быстро на заре изучения программирования, но по мере возрастания кода, объемов работы и сложности предметной области, перед программистами встает задача - правильно идентифицировать переменные, константы, функции и методы. Тут, как показывает практика, начинается полнейший хаос, который влечет как минимум потерю времени на изучение ранее написанного кода и переименование переменных и функций.

Проблема № 1. Сокращения идентификаторов

Когда мы читаем сокращённое слово, то наш мозг, на основе нашего жизненного опыта и знаний, поневоле начинает анализировать возможные комбинации сокращения, тратя на это определенные ресурсы. Вот что говорит нам о сокращениях "Справочник издателя и автора", ISBN 5-224-04565-7:

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

И это - рекомендации для авторов, пишущих книги на родном языке читателя. Что же происходит в программировании, когда программисты пишут код с применением сокращений для англоязычных слов? Сложность понимания такой программы увеличивается в 2 раза: читающий код вынужден теперь не только найти англоязычный эквивалент сокращения, но и перевести его, удержав при этом логику программы у себя в голове.

Недавно мне была поставлена задача - закончить работы за программистом, который был перекинут на другой проект. Начав разбирать код, я столкнулся со следующими идентификаторами переменных:

Было: $wcode_prim $wcode_acc $prty_acc $prty_show $type_fld

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

Сценарий пришлось переписать, введя полноценные, понятные имена для переменных:

Было: $wcode_prim $wcode_acc $prty_acc $prty_show $type_fld
Стало: $code_primary $code_accessory $priority_group $priority_show $field_type

Теперь идентификаторы были написаны полностью, без сокращений. Кроме того, я полностью переименовал некоторые переменные согласно их описанию в ТЗ: $prty_acc стал называться $priority_group, что означало "Приоритет группы".Читать и понимать такой код стало проще.

Проблема № 2. Ошибки в написании идентификаторов

Ошибки в написании неразрывно связаны с попустительством разработчиков. Реальный пример: разработчик интернет-магазина создал таблицы, содержащие информацию о товарах и обозвал поле, содержащее ID товара английским словом wares (изделие). Другой разработчик, при создании дополнительной таблицы связи, не удосужится посмотреть в словарь и обозвал поле как warez (такого слова в официальном английском я зыке нет). В конечном итоге в проекте стали существовать идентификаторы, схожие по написанию. К чему это привело?

  • При написании SQL запросов разработчики, даже если и помнят на память, что в определенной таблице есть поле ware(z|s) с уверенностью не могут сказать, как правильно пишется имя этого поля. Приходится смотреть структуру таблицы данных.
  • В программном коде данные, полученные из СУБД, транслируются в массивы с соответствующими ключами из СУБД. Следовательно, в коде также присутствует два стиля наименования одного и того же типа данных. Следовательно, возрастает вероятность ошибки.

Проблема № 3. Написание идентификаторов по-английски и по-русски с помощью транслита.

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

// Правильно. Английское слово "комплекты"
$packages = array();

// Отвратительно.
$komplekti = array();

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

// Можно так написать:
$komplekti = array();

// А можно так написать:
$komplekty = array();

// А можно и так:
$complekti = array();

// И даже так!
$complekty = array();

Плюс ко всему писать идентификаторы на английском - это изучение языка в процессе работы. Совмещаем приятное с полезным.

Проблема № 4. Отсутствие стандартизации в написании идентификаторов

В одном проекте, с которым я работал, существовало 4 таблицы в СУБД, они представляли собой справочники для иерархической вложенности каталога продуктов и использовались практически всегда вместе. У каждой таблицы был свой первичный ключ:

Имя таблицы dir class group mark
Имя первичного ключа таблицы dir_id class_id gr_id mark_id

Когда я работал с этими таблицами, то периодически имя первичного ключа таблицы group писал как group_id, по аналогии с именами первичных ключей данных четырёх таблиц, которые именовались в соответствии со стандартом имя-таблицы_id. Первичный же ключ таблицы group назывался не по стандарту, он почему-то был назвал как gr_id (очевидно, по тем самым причинам). Это приводило к ошибкам и трате времени на их поиски.

Как видно, стандартизация в написании идентификаторов помогает не отвлекаться на банальные ошибки.