Pull to refresh

Код, который невозможно поддерживать

Reading time7 min
Views11K
Original author: Roedy Green
Вольный перевод с сокращениями первой части эссе «Unmaintainable Code». Именование переменных — довольно банальная тема (хоть и забавно изложенная), но без этой части эссе было бы неполным.

Пролог



Это самое популярное из моих эссе. Удивительно, сколько людей не понимают, что это насмешка.

Это эссе написано ради создания рабочих мест для программистов на Java. В нем я собрал советы мастеров о том, как писать код, который так сложно поддерживать, что люди, пришедшие после вас, потратят годы на внесение даже минимальных изменений. Более того, скрупулезное следование этим советам обеспечит вам занятость до конца жизни, так как ни у кого другого нет шансов на успешную поддержку кода. Впрочем, если вы следовали всем правилам, шансов на это нет даже у вас.

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

Общие принципы



Quidquid latine dictum sit, altum sonatur.
Что сказано на латыни, звучит внушительно.


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

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

Именование



— Когда я использую слово, — сказал Шалтай-Болтай презрительно, — оно значит только то, что я имею в виду — не более и не менее.

Значительная часть искусства написания неподдерживаемого кода заключается в именовании переменных и методов. Они ничего не означают для компилятора, и следовательно, предоставляют вам неограниченные возможности для того, чтобы поставить в тупик сопровождающего.

1. Однобуквенные имена переменных

Если вы называете свои переменные a, b, c, их будет невозможно искать в простом текстовом редакторе. Кроме того, никто не догадается, для чего они нужны. Если кто-нибудь упомянет о нарушении традиции называть счетчики циклов i, j и k, чтимой со времен FORTRAN, методом замены их на ii, jj и kk, упомяните о том, что испанская инквизиция делала с еретиками. Напротив, используйте имена i, j и k для чего угодно, кроме счетчиков циклов.

2. Креативные опечатки

Если вы вынуждены использовать описательные имена, делайте в них ошибки. Не во всех: ошибка в одном названии из логической пары (например, SetPintleOpening и SetPintalClosing) эффективно нейтрализует использование grep или поисковых средств среды разработки. Добавьте интернационализацию по вкусу: пишите tory или tori в зависимости от локализации.

3. Будьте абстрактны

Используйте абстрактные слова и понятия (it, everything, data, handle, stuff, do, routine, perform), а также цифры: routineX48, PerformDataFunction, DoIt, HandleStuff и do_args_method.

4. А.К.Р.О.Н.И.М. / псть скрщнми грзд интрсн

Используйте аббревиатуры для сокращения кода. Настоящие мачо никогда не объясняют аббревиатуры: их понимание у них в крови. Если вы так сразу не можете, быстренько напишите код с осмысленными именами, а потом автоматически переименуйте все переменные и методы. Если одно понятие можно сокращать несколькими способами — используйте их все: это поможет в борьбе с теми лентяями, которые пытаются постичь вашу программу простым текстовым поиском. Используйте также американизмы (для нашей локали, надо полагать, рекомендуются украинизмы — прим.пер.) и сленговые написания.

5. Синонимы

Пролистайте словарь в поисках максимально возможного количества синонимов для одного и того же действия (например, display, show, present). Используйте их, чтобы указать на то, что разница есть, когда на самом деле ее нет. Напротив, для именования существенно разных функций используйте одно и то же слово (например, print для обозначения «печать чернилами на бумаге», «запись в файл» и «вывод на экран»).

6. Избегайте написания глоссария проекта

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

Если вы все-таки вынуждены написать глоссарий, используйте рекурсивные определения. Пример, взятый из руководства по Ant 1.6.5: «basedir: абсолютный путь к basedir проекта (задается в аттрибуте basedir проекта)». Читателю все равно непонятно, что такое basedir, хотя он может предположить, что это абсолютный путь, несмотря на примеры, в которых он начинается с ., то есть является относительным.

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

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

7. Множественное число по правилам других языков

Отлично подходят Эсперанто, Клингонский язык и вестрон. В псевдо-эсперанто множественное число образуется добавлением oj. Таким образом вы поддерживаете мир во всем мире.

8. веРхНий реГисТр

Произвольно переводите в верхний регистр первую букву слога, а также другие буквы.

9. Повторное использование имен

Во всех случаях, допускаемых синтаксисом языка, давайте классам, методам, членам-переменным, параметрам, глобальным и локальным переменным одинаковые имена. Желательно повторно использовать локальные переменные внутри блоков {}. Это делается для того, чтобы сопровождающий внимательно изучил область видимости каждой переменной. В зависимости от языка возможности повторного использования варьируются, но почти всегда можно найти способ вставить в код приятную мелочь: передавая в функцию переменные A и B, в сигнатуре функции менять их местами; использовать одну переменную для разных целей или просто слегка изменять ее назначение.

10. Акцентированные буквы/расширенный ASCII

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

11. Ограничения длины имен компилятора

Если компилятор различает только первые, скажем, 8 букв имени, варьируйте окончания, например, var_unit_update() в одном случае и var_unit_setup() в другом. Компилятор будет трактовать оба названия как var_unit.

12. Подчеркивание — ваш друг

Используйте _ и __ в качестве имен переменных. Кроме того, неплохо работает дописывание пары-тройки подчеркиваний в начало и в конец имени переменной для получения новых переменных, желательно другого типа и назначения.

13. Вавилонская башня

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

14. Значащие имена переменных

Если уж приходится использовать значащие имена переменных, выбирайте такие, значение которых прочно ассоциируется с чем-то из совершенно другой предметной области. Неплохо работают названия математических символов:
openParen = ( slash + asterix ) / equals;
или имена с сильной эмоциональной окраской:
marypoppins = ( superman + starship ) / god;

15. Скажите соглашениям «нет»

Игнорируйте общепринятые соглашения, регулирующие внешний вид кода, в частности, Sun's coding conventions и Hungarian notation. К счастью, компилятор на это не отреагирует. Кроме того, можно придумать свои собственные соглашения и обвинять всех остальных в том, что они их не используют.

16. Сходные символы

В большинстве шрифтов есть пары символов, имеющих сходное начертание: l и 1, 0 и O, g и q, m и rn и т.д. Используйте их! Исключите из обихода любые шрифты, в которых эти символы сильно отличаются.

17. Сбивающие с толку имена методов

Убедитесь, что каждый метод делает чуть меньше или чуть больше, чем обещает его название. Например, метод isValid(x) может иметь побочный эффект в виде записи x в базу данных в двоичном виде.

18. Отсылки к шедеврам мировой культуры

Вместо blue назовите константу 0x0204FB LancelotsFavouriteColour. Этот цвет выглядит точно так же, как обычный синий, и сопровождающему придется помучиться, выясняя код цвета. Конечно, только человек, свободно ориентирующийся в Monty Python and the Holy Grail, догадается, что любимый цвет Ланселота — синий. С другой стороны, если сопровождающий не способен даже процитировать фильмы Monty Python по памяти, что он вообще делает в программировании?

19. Цветные развлечения

Само собой разумеется, что вместо имен цветов должны использоваться их числовые значения. К сожалению, большинство сопровождающих уже выучили, что шестнадцатеричные коды легко расшифровываются, поэтому использовать следует десятичные коды. Ни один нормальный человек без калькулятора не расшифрует 132347 как синий цвет. В идеале нужно подбирать цвета, десятичная запись которых является шестнадцатеричной записью каких-то других цветов. Так, например, 808000 на самом деле является 0x0c5440.
Кроме того, можно поиграться с переименовыванием цветов: очень немногие люди знают, как на самом деле выглядят puce, teal и papayawhip, а это оставляет простор для переназначения цветовых констант.

20. Достижения передовой психологии

Помните, что человеческий мозг может комфортно обрабатывать не более 7 фрагментов информации одновременно? Пользуйтесь этим. Создавайте имена переменных, несущие информацию нескольких ортогональных типов (тип и область видимости переменной, ее происхождение и назначение, а также дату создания). Придавайте логике программы вид сложной вложенной структуры; оптимальный размер блоков несколько превышает количество строк, помещающихся на экран.
Tags:
Hubs:
+95
Comments58

Articles