Не судите чужой код строго

?v=1

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

То же самое относится к чтению чужого кода: если его автор сидит по левую руку от вашего трона, работает в вашей фирме 10+ лет и зарабатывает на один ноль больше вас, это совершенно не то же самое, что автор, которого уволили за что-то плохое, а вас наняли на его место. Но по сути то и там и там код — это всего лишь набор байтов, которые было бы полезно оценивать без привязки к авторитетности источника.
Когда мы читаем чужой код, нас могут посещать самые разнообразные эмоции: восхищение, смех, раздражение, разочарование, полное неприятие. Полезно знать о том что проявление любых эмоций в любом контексте — это автоматический ответ низшего (первого) уровня нервной системы, сформированный эволюционным путем, необходимый в первобытной среде. Основная задача такого ответа, в случае «негативной» эмоции — запустить механизм действий «бей или беги» с одной единственной целью — выжить. В нашей текущей офисной среде при анализе чужого кода подобный ответ становится скорее бесполезным и даже вредным, поскольку вы тратите на него драгоценное время и ресурсы, плюс загрязняете свой мозг нейромедиаторами, понижающими вашу сообразительность в угоду скорости реакции. Хорошая новость в том что этот ответ можно перепрограммировать. Можно подавлять негативные эмоциональные реакции, а можно их инвентировать, например, смеяться там где вы раньше злились. Смех, в отличие от злости, выбрасывает в мозг хорошие вкусные полезные нейромедиаторы, доставляющие удовольствие, закрепляющие опыт и мотивирующие на дальнейшую работу.

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

Современные средства разработки позволяют практически на лету преобразовывать чужой код в более понятные и приятные структуры. Функция или переменная плохо названа — ctrl+shift+R и в пару секунд она называется по хорошему. Табуляции вместо пробелов, неудобно, непривычно раскиданы отступы и открывающиеся бракеты в египетском стиле — ctrl+shift+F и форматирование восстановлено! Комментарий избыточен или устарел — ctrl+D и его нет. Если изменить призму восприятия, чтение чужого кода может превратиться в увлекательную интерактивную детективную игру.

Код это всего лишь инструмент. Как бы плохо и ужасно он не был написан, в конкретное время и в конкретном месте он успешно решал конкретную проблему, а значит он уже «оправдан». Что-то изменилось в бизнес-требованиях, что то было не учтено — код поломался или стал не актуален, и это нормально. Код имеет свойство эволюционировать самыми разными путями: и постепенно, обрастая пластами и революционно, переписываясь с нуля. Конечно хорошо, когда программист предвидит будущее и на начальных этапах закладывает в код возможности для дальнейшего его развития. Но эта секира остра с двух сторон, вы можете ошибиться с предсказыванием будущего, будущее может не наступить вовсе, а время и ресурсы будут безвозвратно утеряны. Тут важно понимать код какой степени качества от вас требуется. Если это огромная распределенная система, модули к которой программируют ваши коллеги из самых разных точек земного шара в фирмах слабо связанных с вашей, тогда да, имеет смысл использовать модные паттерны, оборачивать модули в сервис-контейнеры даже там где вы не можете себе представить зачем это нужно. Но если это маленькая локальная CRM для одной фирмы, модули которой зависят друг от друга настолько жестко, что отключение любого модуля по сути ведет к остановке работы всей системы… в этом случае вполне оправданно вызывать чужие методы напрямую, это уменьшит количество классов, облегчит вашу оперативную память и сократит время на отладку проблем. Но вот возникает ситуация когда маленькая локальная CRM превращается в нечто расширяемое, что ваша фирма хочет выложить в открытый доступ и продавать. Бизнес-требования изменились. Стоит ли винить программиста в том что он не предвидел этого?

Стандартизация


Код это всего лишь инструмент, но его создание — это чистое творчество. Любую задачу можно решить бесконечным числом самых разнообразных способов. Некоторые из них более производительны, чем другие — пример объективной оценки. Некоторые из них более читабельны, чем другие — пример субъективной оценки. Даже если вы убедите весь офис в том что какой-то кусок кода не читабелен, все еще останется как минимум один автор, который с вами не согласится. Стандартизация кода направлена на то чтобы преобразовать чистое творчество в как можно более рутинный набор действий для того чтобы другим программистам было проще разбираться в вашем коде. То есть, по сути, чтобы вас можно было заменить другим специалистом, более покладистым и дешевым. А через пару десятков лет так и вовсе искусственным интеллектом. Стоит помнить, что если какой-то стандарт противоречит здравому смыслу, возможно его имеет смысл нарушать в некоторых местах, а то и вовсе отказаться от него или заменить на другой, более подходящий.

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

Особое внимание занимают стандарты, основательно обосновавшиеся в культуре просто потому что они возникли раньше других аналогичных стандартов. Каноничный пример это святая война между раскладками QUERTY и Дво́рака. Вторая, очевидно, лучше, но первая держит удар (остается популярнее) просто за счет критической массы пользователей, не желающих переобучаться по новому.

Аналогичные примеры встречаются сплошь и рядом и в культуре программирования. Стандарт PSR ратует за 4 пробела вместо табуляции, игнорируя очевидный факт: среда разработки большинства PHP-программистов изменилась с консольных редакторов на полноценные IDE, в которых оперировать табуляциями удобнее во многих смыслах: и удалять проще, нажимая Backspace один раз, и настроить можно индивидуальную длину табуляции по вкусу.

Применяя тот или иной стандарт задавайтесь вопросом: кому вы делаете удобнее? Кому неудобнее? Кому станет лучше от правила «именуем имена методов лоуерКамелКейсом»? Очевидно лишь тем, кто привык их так именовать. Всем остальным станет неудобно, им придется адаптироваться, а это потери времени и ресурсов абсолютно на пустом месте, учитывая то что
а) теперь у нас есть волшебные IDE, подсвечивающие разными цветами разные элементы кода,
б) программисты имеют свойство перескакивать с проекта на проект, стандарты кодирования в которых могут различаться.

Лично я при разработке своих проектов использую:

  • CamelCase для именования классов и методов
  • $CamelCase для именования переменных, содержащих экземпляр объекта
  • $snake_case для именования переменных, содержащих простые типы


У меня нет никаких проблем отличить имя класса от имени метода, поскольку первое — существительное, а второе — глагол. К тому же подсветка выручает. Но это мой личный вкус, я его никому не навязываю. Это персональная призма восприятия, она индивидуальна для каждой отдельной головы. Кому то «повезло» сразу вляпаться в популярный стандарт, кому то «не повезло» начать свою карьеру с альтернативных, а кто-то вообще разрабатывал собственные. Я вас веду к тому, что вместо того чтобы переучивать других, возможно, имеет смысл переучить себя воспринимать код в любых стандартах. Или даже вне стандартов.
Конечно, адепты стандартизирования в этом месте возмутятся и накидают мне множество причин против. Эта статья не для них, я пишу ее для тех, кому интересно проникать в суть вещей, пытаться представить что на самом деле имел в виду автор и какую цель преследовал.

Умение разбираться в чужом коде


Триггер, вызывающий рвотные порывы у подавляющего большинства программистов (пример субъективной оценки). Вам никогда не казалось странным, что зачастую нам проще переписать весь код с нуля, чем разбираться в чужом? В любой другой отрасли мы действуем иначе: сперва учимся читать, потом — писать; сперва пользоваться (электроприборами, зданиями), затем — их проектировать. Мне кажется все дело в нашем образовании (конкретно в области программирования). Нас учат достигать цели самым прямым и быстрым способом, используя некоторые свеже-приобретенные знания. В результате мы комбинируем их (знания) ровно до тех пор пока «оно» не заработает, немного тестируем и отправляем учителю на модерацию. На мой взгляд было бы неплохо добавить в этот процесс дополнительную ступень, на которой мы сравниваем наш код с мастер-кодом, который хоть и не является идеальным и единственно правильным, но дает альтернативный путь решения, зачастую более оптимальный и читабельный.

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

Заключенька


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

© Habrahabr.ru