Коллеги. Вашему вниманию предлагается вторая часть книжки «Не спеша, эффективно и правильно: путь разработки», повествующая о теоретических аспектах. Также автор хотел бы выразить своим читателям две большие благодарности.
Общая благодарность за проявленный интерес, выставленные положительные оценки, лестные комментарии и конструктивное обсуждение. К сожалению, принять в этом обсуждении активное участие у меня сейчас возможности нет, но я постараюсь подготовить небольшой текст на поднятую в обсуждении актуальную тему «Все это хорошо в теории, но 95% реальной практики таковы что 😞». Можно считать небольшим анонсом и уж поверьте, показатель 95% слегка завышен.
Третья, практическая часть будет опубликована через неделю, редактура как раз завершается.
Disclaimer
Коллеги, вашему вниманию предлагается почти финальный вариант моей книжки. Была и остается идея издать это в бумажном варианте, но идея довольно зыбкая. К сожалению, имеются некоторые проблемы со здоровьем. Но очень хочется, чтобы труд не пропал, поэтому книжка отдается в открытый доступ. Можно публиковать где угодно, цитировать и так далее. Единственное условие – ничего в тексте не менять и указывать авторство. Автор текста – Никита Викторович Зайцев (также известный как WildHare).
Книжка повествует об эффективной разработке программного обеспечения. Можно сказать, что это дистиллят моей личной практики, наработанного опыта, знаний и умений.
Предыстория появления книжки в формате интервью порталу Инфостарт:
//infostart.ru/journal/news/mir-1s/nikita-zaytsev-ya-universalnyy-soldat-v-mire-1s_1250753/
Это уже не полуфабрикат, а почти готовый продукт, правда без нескольких не особо важных деталей. Если работу над книжкой получится продолжить, то эти недостающие детали будут добавляться именно сюда, в эти файлы.
Приятного чтения ;-)

Автор в естественной среде обитания – II
Сила светлой стороны
Как и почти в любом деле, сначала нужно изучить азбуку. Будущий специалист по космической связи начинает с изучения азбуки Морзе. Будущий капитан дальнего плавания начинает с парусной морской азбуки. Будущий такелажник начинает с такелажной азбуки, правда, она довольно короткая. Ну — и так далее.
Level zero
Будущему разработчику программного обеспечения так же стоит начинать с изучения азбуки. Не азбуки программирования, разумеется. Программирование — это искусство писать программы. Собственно, хрестоматийная работа Дональда Кнута так и называется. Попробуем сформулировать, в чем разница.
Разработка программного обеспечения — это искусство писать программу так, чтобы издержки на ее написание, на работу с ней, а также на ее сопровождение и развитие были минимальными.
Программист оперирует понятиями изящности, оптимальности, оригинальности. Разработчик программного обеспечения оперирует принципом экономии сил, экономической эффективностью и коэффициентом полезного действия. Это вовсе не значит, что можно писать кривые и неряшливые программы. Разумеется, программа должна быть красивой и оптимальной. Но важно помнить, что сама по себе красота может украсить только музей или подиум. А у нас, извините, но так уж вышло, промышленное производство.
Азбука никогда не бывает длинной, иначе это уже букварь. В нашем случае под азбукой понимается несколько крайне простых, но безусловных принципов. Базовые принципы разработки очень похожи на уставы караульной и конвойной службы. Эти принципы написаны кровью убитых систем, проваленных под землю проектов и утопленных в болоте талантов.
Принцип DRY
По-английски это значит Don’t Repeat Yourself. По-русски — Не Повторяй Себя. Есть и альтернативная аббревиатура, DIE. Duplication Is Evil. Копирование-вставка Есть Зло.
Смысл принципа: одинаковый или почти одинаковый программный код не должен располагаться в двух или более местах. Если ты скопировал фрагмент кода и хочешь вставить в другое место, а потом слегка поправить — бей себя по рукам линейкой. Ну, как раньше делали школьные учителя (и очень жаль, что такую практику запретили, любуйтесь теперь на плакаты и вывески, не говоря о письмах и документах).
Казалось бы, это все-таки принцип программирования, причем здесь разработка? А вот причем. Разработчик пишет не просто программу, он пишет код, устойчивый к изменениям. И допускает, что изменения будут вносить совсем другие люди. У этих людей не будет технической документации, потому что времени составить спецификацию кода, как всегда, не хватило. Эти люди добросовестно перекопают все модули, найдут два места из трех, и доработают логику. А вот до третьего места они не доберутся, слишком уж глубоко закопано. Что будет после обновления? Правильно, именно маленький и пушной. На экране все выверено и правильно, ну а что в налоговую уехали немного другие суммы, потребитель программы узнает чуть позже. Из повестки, например.
Этот же принцип касается не только кода, но и заголовочных комментариев. Просто возьмите любую конфигурацию и посмотрите на однотипные функции. Довольно поучительное зрелище.
Копирование — зло. Не копируйте, пишите. Руки не отвалятся.
Принцип GIGO
По-английски это значит Garbage In Garbage Out. Русский аналог — Мусор на Входе Мусор на Выходе.
Смысл принципа: если на вход алгоритму поданы некорректные или невалидные данные, на выходе получится полная ересь, пусть даже сам алгоритм реализован правильно. Казалось бы, это естественный закон природы. Залив утренние мюсли вместо йогурта жидким мылом странно рассчитывать на полезный и питательный завтрак.
Пример из личной практики автора. Некоему программисту, назовем его Петр, поручили реализацию довольно сложной отчетной формы. Там нужно было собрать хитрые агрегаты из огромного массива сырых данных, а потом еще и вывернуть наизнанку. На выходе одна страничка, что-то вроде черты под балансом. Петр написал изумительно красивую и оптимальную расчетную механику. Но когда стали проверять на продуктиве, вышло примерно так:
— Петр, позвольте, но здесь же отрицательная прибыль. Это как такое может быть? Вы же сами тестировали, вас не смутило?
— Ну и что из того? Отрицательное число такое же число, как и прочие. Алгоритм отработал правильно, что в базе, то и на выходе.
Притом, что бумажка должна была ехать в налоговую, за подписью генерального директора. Лучшего сигнала для проверки не придумать.
Принцип GIGO действительно является законом природы. Разница в практическом следствии. Программист заботится только о корректности работы своих алгоритмов. Разработчик программного обеспечения проверяет и валидирует входные данные, не допуская мусор дальше порога.
— Как вы могли выставить мне счет на два триллиона рублей?
— Ну вы же сами в форме заказа указали “по 31.12.2919”.
— <пять этажей 18+>
Пользователи ошибаются при вводе. Коллеги ошибаются при вызове ваших интерфейсов. Доверять нельзя никому. Проверяйте.
Принцип KISS
Согласно некоторым источникам, этот принцип был сформулирован проектировщиками US Navy в лохматых шестидесятых годах прошлого века. Но к разработке программного обеспечения он подходит идеально.
По-английски это значит Keep It Simple Stupid. Вольный перевод на русский звучит как Упрощай Где Можно Дурашка.
Суть принципа: простые системы всегда работают лучше и надежнее, чем сложные и навороченные. Если задачу можно решить простым способом, используя простые инструменты, именно так и нужно сделать.
Чтобы повесить картину на деревянную стену, достаточно вбить молотком обычный гвоздь. Пневматический молоток и лазерный дальномер в едином комплексе с бортовым микроконтроллером для развешивания картин слегка лишние. Хочешь, чтобы твое чадо не навернулось с продвинутого детского кресла (подогрев, пять режимов качания, встроенный дисплей с возможностью загрузки мультиков через WiFi), сажай на низкую трехногую еловую табуретку. Самая надежная конструкция. Ну, и так далее.
Собственно, KISS прямо запрещает использовать более сложные инструменты, алгоритмы, структуры данных и так далее, чем это необходимо для решения задачи. Не рекомендует, а именно запрещает, категорически.
Ну вот элементарный пример, известный всякому, кто имел дело с одной известной библиотекой. Нужно просто взять контрагента, и записать в базу контактный телефон. Казалось бы, один метод, да? Но это было бы слишком просто. Нужно применить магию типов и видов, вызвать несколько методов с последовательной передачей параметров, не напутать, что куда и откуда переставить, и вот тогда — если повезет, телефон в базу запишется. А если очень повезет, то потом даже и прочитается.
Автор ни в коем случае не хочет отнести крайнюю справа букву аббревиатуры KISS уважаемым коллегам, с которыми провел столько увлекательных совещаний. Но, парни, как так-то? Нужно просто вбить гвоздь, а плотнику вместо молотка выдают строительный станок с ЧПУ, который, если хорошо попросить, сумеет сыграть на перфораторе “Пещеру горного короля”.
Нет ничего проще, чем сделать сложное. Но довольно сложно сделать простое. Будьте проще, и к вам потянутся не только прочность и стабильность, но и добрые слова.
Принцип YAGNI
Нет, индийская мифология здесь ни при чем. Про индийское кодирование мы поговорим в следующей главе. Все гораздо прозаичнее: You Aren't Gonna Need It. Иными словами, Вам Это Не Нужно.
Суть принципа: реализации подлежат только те требования, которые нацелены непосредственно на решение задач, имеющих четкий практический смысл. Все остальное просто не нужно.
Собственно, незнание этого принципа представляет собой первую ловушку для начинающего специалиста по работе с требованиями. Ну а в нашей отрасли таким специалистом является сам разработчик. И вместо того, чтобы поставить перед капризным заказчиком гранитную стену принципа YAGNI
— Какую задачу мы решаем этой свистелкой? Нет ответа? Вам это не нужно.
этот специалист зачем-то превращается в официанта
— Чего изволите? Восьмибитный свист? Хорошо. И чтобы дырочки были восьмиугольными? Запросто. И чтобы если нарисовать в воздухе скрипичный ключ, оно само свистело “Коробейников” из тетриса? Не вопрос, я все записал.
Это какой-то бич отрасли. Заказчику, пользователю, потребителю не нужны программные продукты, как таковые. Ему даром не нужны функции, формы, команды и прочее. Потребителю программного продукта нужно просто выполнить свою задачу с максимальным КПД. И только. Но сам он этого не понимает, и вместо того, чтобы описать задачу, сразу описывает способ решения. Но это ведь то же самое, если бы пассажир на калькуляторе показывал конструктору, какая форма фюзеляжа обеспечивает лучшую аэродинамику.
YAGNI действует и в обратную сторону. Когда разработчики слушают воображаемого заказчика. Собираются и думают, а какую бы еще свистелку приделать, чтобы порадовать наших пользователей? Реальный пользователь получает обновление — что это, зачем оно высвистывает “Коробейников” при расчете? Мне это не нужно!
Собственно, принцип YAGNI в первом приближении сформулировал еще Оккам. Не плодите сущности сверх необходимого.
Принцип недотроги
Описанные выше принципы можно назвать каноническими. Но ими азбука разработки не исчерпывается. Попробуем сформулировать еще один принцип, который относится не просто к разработке, но к самому трудному ее виду — сопровождению. Автор называет это “принципом недотроги”, но наверняка есть десяток других названий.
Прежде всего, что такое сопровождение и в чем отличие от поддержки? Поддержка подразумевает эксплуатацию системы без возможности внести какие-либо изменения. Специалист поддержки просто рассказывает пользователю, как правильно работать с системой, то есть выполняет роль проводника через болото. А вот сопровождение не просто разрешает изменения, но и требует их — мир меняется, бизнес меняется, правила меняются, и система тоже должна меняться.
Суть принципа: не уверен, не трогай. Даже когда в системе что-то кажется странным, ошибочным, избыточным, но нет четкого понимания, зачем оно такое, и что может случиться, если это что-то исправить — убери руки за спину, не трогай.
Этот принцип лучше всего показать на примерах, так что самое время запустить кофе-машину. Примеры, само собой, из реальной практики.
Кофе-пауза #4
Пример первый. На некоем предприятии эксплуатируется довольно серьезна система. Ведущий разработчик системы, назовем его Петр, условно первый (a.k.a. Петр-строитель), построил систему с нуля, запустил и наладил. Но поскольку первому поколению Петров гораздо интереснее строить, чем сопровождать, он заскучал и отчислился с предприятия, покорять новые вершины профессии.
Сопровождать систему был призван другой специалист. Назовем его Петр, условно второй (a.k.a. Петр-эксплуатант). Это был прирожденный специалист по сопровождению, строить он не любил, выходило как-то кривовато, а вот дорабатывать и развивать уже готовое — совсем другое дело. Петр-эксплуатант был очень аккуратным, терпеть не мог неряшливости, у него все и всегда было разложено по полочкам.
Первым делом Петр-эксплуатант обследовал конфигурацию. Фу, сказал он. Ну вот кто не сортирует метаданные по алфавиту? И отсортировал. Все, не только верхний уровень. Разумеется, Петр-эксплуатант знал, что нельзя сортировать только измерения регистров, все же он был настоящий специалист.
После обновления... После обновления система не просто упала. Если бы упала, то ничего. Но все расчетные функции стали выдавать на выходе какую-то немыслимую ересь. Петр-эксплуатант был в полном непонимании, он же ничего не делал, просто сортировка по имени?
Расследование показало, что в конфигурации есть незаметное перечисление, МесяцГода. Просто названия месяцев. И есть еще более незаметная функция в расчетном ядре системы, которая по ссылке на это перечисление формирует дату начала месяца. И какой месяц пришел на вход, эта функция определяет — правильно, базируясь на порядковый номер значения. То есть на тот самый лохматый порядок, когда Январь, Февраль, и так далее. Одним движением Петр-эксплуатант превратил Январь в Август, поменял местами Июнь и Май, ну и так далее, прямо как в сказке.
Уж как там икалось Петру-строителю, история умалчивает.
Пример второй. Тоже серьезное предприятие и серьезная система, и тоже написана с нуля. Система довольно сложная, спарка из двух информационных баз с крайне затейливой интеграцией. “Крайне” в данном случае следует понимать буквально.
Разработал и запустил систему коллектив неких добрых людей, но затем добрые люди не поладили с руководством предприятия по вопросу о стоимости сопровождения. К доводам “с этой системой справимся только мы” руководство осталось глухо, что же с шантажистами разговаривать? Добрые люди отправились искать новое поприще, и на царство, как водится, был призван Петр-эксплуатант. Возможно, даже тот самый, кто знает?
Петр-эксплуатант, разумеется, начал с ревизии своих владений. Ну а войдя во вкус, занялся любимым делом — привести в порядок, разложить по полочкам, убрать лишний мусор. В конфигурациях А и Б, назовем их так, обнаружились какие-то уж совсем диковинные вкрапления мусора, комментарии с какими-то кракозябрами прямо внутри кода. Ни малейшего смысла в кракозябрах, на первый взгляд, не было. Петр-эксплуатант был чистюлей, лишний мусор не терпел. Поэтому взял глобальный поиск, посидел вечерок-другой, и все лишнее из кода вычистил.
После обновления... После обновления система не упала, нет. Если бы упала. Система пошла в полный разнос и раздрай. Все горело и рушилось. Фильм “2012” в отдельно взятой операционной системе. Петр-эксплуатант был в ужасе, он же ничего не делал, просто вытер какие-то лишние комментарии?
А дело было вот в чем. Спарка действительно была крайне хитрая. База А была управляющим контуром, ее конфигурацию можно было обновить в любой момент. А база Б была рабочим, нагруженным контуром, для нее технологическое окно для обновления нужно было каждый раз согласовывать, и ответ на запрос мог иметь вид “завтра в 23:50”. Кому же из добрых людей хочется ждать до завтрашней ночи, чтобы чуть-чуть подправить логику в коде? Тем более, что пользователи шипят уже по-злому. Динамическому обновлению тогда никто не доверял, а расширения еще не придумали.
Было изобретено инженерное решение. Часть кода была написана, скажем так, в стиле “мехом наружу, дважды, с морским узлом”. В подробности вдаваться не будем, важна суть. Чтобы не останавливать рабочий контур, в конфигурацию вписывались кракозябры (был разработан свой псевдоязык), конфигурацию базы А обновляли, давали команду базе Б, та забирала конфигурацию А в файлы, читала их, разбирала кракозябры и соответствующим образом подстраивала свое поведение.
Автор понимает, что это звучит как сон разума. Собственно, это и был сон разума, об этом подробно будет в следующей главе. Какой там KISS, это hardcore SM в чистом виде. Почему было сделано именно так? Ирония в том, что добрым людям это показалось простым и надежным решением. Конфигурации А и Б полностью тождественны по метаданным и формам, а вот ключевые участки кода Б (в первую очередь, разнообразная расчетная механика) могли замещаться кодом из А, через сложносочиненный стек из “Выполнить/Вычислить”. Эрзац-расширение из ветхого полотна, компоста и фрагментов древесных стволов. Плюс все кракозябры в хранилище, никаких внешних файлов, просто пересобрать, обновить и нажать одну кнопку. Ну и заодно представьте себе, сколько заплатило предприятие добрым людям за разработку и отладку этого монстра. Лишний раз прокатиться к теплому морю никому не вредит, работа-то нервная, на износ.
Вопрос, а должен ли был Петр-эксплуатант знать о том, что кракозябры в коде не просто так? В теории — разумеется, должен был знать. Добрые люди оставили новому поколению пухлую пачку технической документации, где вся механика была описана в деталях, и даже с UML-диаграммами. Но кто читает документацию?
Тут автор должен сделать небольшое лирическое отступление и отдать дань уважения человеку, без которого эта книга никогда не была бы написана. Будем надеяться, что до этого места он дочитает и узнает себя. Уважаемый коллега и дорогой товарищ. Да, документацию действительно почти никто не читает. Горек хлеб технического писателя, и стезя его усыпана крупным гравием. Но Север — помнит.
Сила темной стороны
Как и у всякого природного явления, у любой силы есть две стороны, темная и светлая. Искусство разработки программного обеспечения исключением не является, у него есть своя темная сторона. В предыдущем разделе мы попробовали сформулировать светлые паттерны разработки, ну а сейчас самое время заглянуть за Стену.
На всякий случай автор подует на воду: все приемы и паттерны разработки, описанные в этом разделе, являются типичными и ярчайшими примерами того, как делать ни в коем случае не нужно, никогда и ни при каких обстоятельствах. Текст будет довольно злым, если прошлая глава была мотиватором, то здесь в ход придется пустить stimulus.
Чтобы избежать голословности, описание некоторых темных паттернов снабжено примерами, причем не синтетическими, а из реальных разработок.
И еще — эрудированный читатель наверняка заметит некоторые фразы с Lurkmore, в авторской, понятно, редакции. Но это не плагиат, а цитирование. Пушкина, например, тоже цитируют без указания авторства на каждой строке.
Простейшие
К группе простейших антипаттернов (именно так это называется) относится абсолютно бездумная деятельность по написанию кода. Если рассматривать такое творчество беспристрастно, возникает ощущение, что головной мозг при работе рук не был задействован от слова “совсем”. Каким-то странным образом у этого вида руками управляет даже не мозжечок, а сразу спинной мозг, и как бы даже не костный. Сном разума это назвать нельзя, для сна нужен хоть какой-то разум.
Китайский стиль
Этот стиль разработки (мы ведь говорим не только про написание кода, но про разработку на платформе в целом) обычно называют китайским. Простота, брутальность, и неспособность открыть для себя даже такой примитивный феномен, как цикл с локальной переменной.
Отличительный видовой признак китайского стиля — эталонное нарушение принципа DRY. Если что-то можно скопировать и вставить, это будет скопировано и вставлено. Если нельзя, то все равно будет скопировано и вставлено, упорство и труд перетирают в пыль любые законы природы. Когда рассматриваешь примеры, возникает впечатление, что им платят построчно, как поэтам начала прошлого века.
Рассмотрим пример. Задача: требуется преобразовать целое число к строке фиксированной длины с ведущими нулями.
Китайское решение:

Человеческое решение:
Подсчитать количество недостающих нулей и добавить их к исходному номеру в цикле.

Экспертное решение:
Воспользоваться встроенной функцией платформы.

Индийский стиль
Этот стиль обычно определяют как “написанный наиболее неочевидным и противоественным способом программный код, который каким-то образом все же работает (хотя и не факт, что правильно)”. Англоязычные товарищи дали индийскому стилю прозвище Write Only, поскольку чтению и анализу такой код не поддается в принципе. Это примерно то же самое, как пытаться понять, о чем же на самом деле повествует “Бхагават-гита”, имея в руках только исходник на санскрите.
Есть довольно известная шутка, что аутентичный индийский код настоящие мастера не пишут, а поют и танцуют. Затем переводят на хинди/суахили, а уже затем транслируют в необходимый язык программирования. Автор может поручиться, что это не совсем шутка, поскольку лично был знаком с настоящим мастером индийского стиля. Правда, вместо пения был художественный свист, а танцевать, сидя в кресле, не так и просто, но у него получалось. Процедура в три тысячи строк, на вход которой подается двадцать два параметра, причем поведение управляется не только значением параметра, но и его типом — это далеко не вершина мастерства, так, предгорья.
Рассмотрим пример. Фрагмент кода выполняет элементарную задачу: проверить, является ли переданное значение числом.

Специалист, которому будет поручено сопровождение этого кода, зависнет над этим фрагментом надолго. Зачем здесь Попытка? Зачем возвращать Число(0)? Почему именно при -1111 наша система будет считать валидные входные данные мусором?
Крестьянский стиль
Этот стиль можно выразить как “крестьянин трудолюбив, но не доверяет этим городским штучкам”. Видовые признаки крестьянского стиля — сознательный отказ не только от “ненадежных” (по мнению крестьянина) библиотечных функций, но даже и “ненадежных” методов платформы, и даже в самых простых ситуациях. Если в случае прикладных библиотек такой подход иногда, к сожалению, бывает уместен (об этом мы поговорим в третьей части, которая целиком посвящена практическим аспектам разработки), то в случае платформы принцип “зачем трактор, если в руках мотыга” выглядит, мягко говоря, неэффективным.
Нужно сделать небольшую оговорку. Антипаттерны темной стороны вовсе не обязательно ведут к ошибкам и проблемам. Код, написанный посредством таких антипаттернов, может быть вполне работоспособен. Но мы говорим не просто о разработке, а об эффективной разработке. Если паттерн снижает эффективность, значит, это плохой, негодный паттерн.
В качестве эталонного примера перелистаем чуть назад и повторим фрагмент из китайского примера. Задача, напомним, проще не бывает: привести число к строке заданной длины и дополнить слева ведущими нулями.
Вместо того, чтобы решить задачу однократным вызовом оператора Формат, крестьянин будет трудолюбиво вспахивать поле мотыгой и делать всю работу руками. Ну а поскольку принцип DRY крестьянину неизвестен, этот фрагмент кода при необходимости будет размножаться копированием на все участки конфигурации. Смекалистый крестьянин даже внесет его в файл шаблонов, и вместо простой мотыги у него будет механизированная.
Тяжелый ручной труд — дело хорошее и правильное, с этим не поспоришь... Но с эффективной разработкой совмещается плохо.
Беспозвоночные
Группа беспозвоночных антипаттернов стоит на гораздо более высокой ступени развития, нежели простейшие. Здесь уже почти полный порядок с владением самыми базовыми методами (никого из беспозвоночных не удивишь, например, циклом), в деятельности уже задействован мозг, но, к сожалению, только одним полушарием. Причем какое именно это будет полушарие, правое или левое, диктуется не только личными качествами носителя антипаттерна, но и конкретной задачей, и даже расположением звезд.
Общие видовые признаки — тотальное пренебрежение логикой (даже не формальной, а обычной, бытовой), элементарными принципами разработки, наличие в коде огромного количества детских ошибок, использование методик “копировать-вставить-подправить”, “завалим-запинаем”, “исключения придумали трусы”, и тому подобных везде, где только возможно.
Носители этого антипаттерна могли бы взять девизом слова известного литературного персонажа по имени майор Прыщ:
Новых идей не понимаю. Не понимаю даже того, зачем их следует понимать-с.
На практике беспозвоночный вид антипаттернов часто идет рука об руку с методикой Google-driven development. Поискать что-то похожее на решение своей задачи (как вариант, поклянчить на сетевых площадках у более опытных товарищей), стянуть к себе и попробовать из чужого кода выпилить лобзиком свой. Характерным является и отношение к языку программирования — он считается чем-то вроде набора заклинаний. Нужно просто подобрать правильные слова, вычертить мышкой определенную фигуру, а дальше волшебная сила все сделает сама. Эталонный представитель такой школы — небезызвестный Григорий Чайников (a.k.a. Harry James Potter).
— Filus chitatus exelus! Documentus convertatus!! Obmenus oshibkus sginus!!!
Ну или как-то так. Беда в том, что написанный таким образом программный код пытается работать (именно пытается, полностью он не работает никогда) на живых предприятиях и у живых потребителей. Как бульдозером по влажному тропическому лесу.
Школокод
Обычно такой стиль разработки называют более грубым словом, но мы постараемся от грубостей воздерживаться. Англоязычные товарищи называют носителей этого антипаттерна Code Monkey, что гораздо точнее раскрывает суть явления. В качестве видовых признаков можно перечислить абсолютное непонимание основных стандартов и особенностей используемого языка, незнание не только лучших, но и базовых практик, а главное, отсутствие желания со всем этим познакомиться хотя бы шапочно.
Как следствие, носитель антипаттерна принимает неочевидные, неверные, а часто и просто абсурдные решения — результат, как гласит поговорка, слегка предсказуем. Написанный посредством этого антипаттерна код находится даже не в световых годах от здравого смысла, а где-то в злой параллельной вселенной.
Вторичные видовые признаки включают в себя общую языковую безграмотность (не только в программировании, но и в русском), неумение и нежелание выразить свою мысль связно, серьезные проблемы не только с культурой разработки, но и вообще с абстрактным мышлением. Ну и лень, разумеется — не благородная лень настоящего мастера, который изобретает инженерное решение, позволяющее получить лучший результат с меньшими затратами, а обычная, подростковая, когда даже прибраться в своей комнате это уже проблема.
Представьте себе паренька в кепке, турецкой кожаной куртке, заправленной в тренировочные штаны, зажатой в зубах сигаретой, сидящего на корточках с пакетом семечек — это почти точное ощущение, которое возникает при просмотре такого программного кода. Любые правила, любые ограничения, любая строгость языка — все это воспринимается как личное оскорбление.
Зачем столько лирики? Тема действительно больная, поскольку носителей антипаттерна, к сожалению, в сообществе очень много, именно из-за них термин “1С-программист” в профессиональной среде обрел негативную и комическую коннотацию.
Разбирать конкретные примеры автор смысла не видит — будет очень много кода и очень много букв, а у нас все-таки теоретический блок.
Шизокод
Как известно из медицинских справочников, характерными симптомами шизофренического расстройства психики являются зрительные и слуховые галлюцинации, а также дезорганизованность речи и мышления. К сожалению, даже вполне вменяемые разработчики порой порождают код, вызывающий у читателя легкий ступор и потерю ощущения сцепления с реальностью.
Подчеркнем еще раз: в разборе этого антипаттерна термин “шизофрения” относится ни в коем случае не к разработчику, а только к написанному им коду. Также отблеск антипаттерна во всей красе можно увидеть в многочисленных сообщениях пользователям, особенно в сообщениях об ошибках.
— Обработка завершена. Внимание! При выполнении обработки возникли ошибки!!! Процедура успешно выполнена.
— WTF? O_O
Стоит привести пару простых примеров, из реальной практики. Просто представьте, что этот код пришел к вам на аудит.
Пример #1
Фрагмент кода выполняет крайне простую задачу: уведомляет пользователя о завершении обработки данных.

Здесь:
- Взаимоисключающие параграфы. Обработка одновременно и выполнена успешно, и выполнена с ошибками.
- Дезориентация пользователя. Кроме сообщения о том, что возникли ошибки (в двух разных вариантах), система не даёт больше никакой информации. Пользователь должен догадаться сам, куда смотреть и что делать.
Пример #2
Фрагмент кода выполняет крайне простую задачу: копирует значения реквизитов элемента справочника в реквизиты обработки.

Здесь:
- Имя реквизита БанковскийСчетВыгрузки подразумевает (как это принято среди разработчиков на платформе 1С) тип значения СправочникСсылка.БанковскиеСчета. Но в реальности реквизит имеет тип СправочникСсылка.ПравилаОбменаКлиентаБанка – тот специалист, который будет заниматься сопровождением кода, слегка поцарапает себе мозг об это несоответствие.
- Обращение к реквизитам объекта ссылочного типа «через точку». Грубейшее нарушение стандартов разработки.
- «Однотипные» реквизиты почему-то имеют разные имена в справочнике и в обработке. Это вызывает к жизни портянку кода вместо оператора ЗаполнитьЗначенияСвойств, и отнюдь не упрощает сопровождение кода.
- Хардкод имени файла в модуле обработки. В подобных случаях константы, если параметрическая настройка для них является избыточной, должны располагаться в соответствующих функциях общего модуля ФункцииПовторногоИспользования.
Пример #3
Фрагмент кода выполняет крайне простую задачу: в зависимости от выбранного пользователем вида операции либо выводит табличный документ для просмотра, либо выводит этот же документ на печать.

Здесь:
- Числовая константа в качестве кода «вида операции». Это абсолютно неестественное сопоставление: «0» ассоциируется с «пустым местом», «первым элементом», «началом списка», но никак не с «печать с предварительным просмотром».
Возможные правильные решения:
- Использовать строковые константы: РежимПросмотр, РежимПечать.
- Так как вариантов всего два, и расширение их количества не предполагается, достаточно использовать булевский флаг ЭтоПечатьНаПринтер.
TurDuсkEn
Этот стиль назван именем блюда североамериканской кухни. Технически блюдо представляет собой индейку (turkey), фаршированную уткой (duck), в свою очередь фаршированной курицей (chicken). Блюдо невероятной калорийности и вредности, кулинарный гротеск, ночной кошмар диетолога — но любителей хватает.

В кулинарной аналогии этот паттерн кодирования выглядит примерно так.
Применительно к разработке программного кода словом TurDuсkEn называют манеру не просто приготовить “лапшу”, перемешав на одном участке принципиально разные сущности, но еще и сделать это на различных языках программирования одновременно.
Чаще всего антипаттерн применяется в разработке веб-приложений. Разработчик-кулинар Петр закатывает рукава и кладет первый слой, PHP-логику. PHP-логика генерирует HTML-разметку и JS-логику. JS-логика собирает фрагменты SQL-запросов. SQL-запрос при желании, и, если позволяет СУБД, тоже можно фаршировать чем-нибудь скриптовым. Которое будет формировать набор данных для другого, внешнего скрипта на каком-нибудь Python, который… ну, идею вы поняли. На выходе получается чистейший turducken, дополненный морской свинкой и парочкой анчоусов в придачу. Блюдо такой убийственной силы, что попытка вручить это для сопровождения сколько-нибудь опытному разработчику запросто может завершиться заявлением об уходе, а то и жалобой в общество защиты людей от животных.
Платформа “1С” обладает не такими богатыми возможностями для смешения языков, как веб-платформы, но и на нашей кухне антипаттерн встречается гораздо чаще, чем хотелось бы. Прежде всего это касается техники “собрать текст запроса сложным кодом с множеством ветвлений”. Казалось бы, уже довольно давно у объекта Запрос появился вполне сносный программный интерфейс, так зачем же собирать текст конкатенацией и заменами в двадцатиэтажной конструкции “Если - Иначе”, врагу на страх, себе на горе? Вопрос, к сожалению, риторический, “пишем, как привыкли”. В эту же категорию попадает ручная сборка shell-скриптов (bat, vbs, ps, etc.), запросов к внешним источникам данных (ADO, и иже с ним), HTML-разметки для внешних и внутренних страниц, ну — и так далее.
Почему turducken является безусловным злом? Применение этой техники на ровном месте усложняет код на порядок, а возможно, и больше. Отладка и сопровождение обычного кода сродни попытке уследить за разбегающимися в разные стороны сотнями тараканов, а в случае turducken-кода тараканы разбегаются сразу в пяти измерениях. Логика генерирует другую логику, ошибки в разных слоях накладываются друг на друга, вызывая самые неожиданные эффекты. Код при turducken-подходе стремительно теряет ключевые качества — понятность, прозрачность и, как следствие, управляемость. Взамен же разработчик получает не “гибкость”, а кратное увеличение трудозатрат на отладку.
Каков правильный способ, если нужно все-таки генерировать какую-то управляющую логику на другом языке? Лучше шаблона с подстановкой параметров и заменой ключевых сигнатур еще ничего пока не придумано. Разных птиц следует подавать на разных тарелках.
Позвоночные
Как и в живой природе, более развитые существа являются и наиболее опасными. Антипаттернов разработки это касается в полной мере. Если носитель антипаттерна не умеет даже склепать простейший цикл, большой беды от его деятельности не будет. Например, на каком-то конкретном небольшом предприятии “система” будет стартовать десять минут, выполняя некую инициализацию прямым перебором всех объектов данных (пример из личной кунсткамеры автора). Или расчет заработной платы будет выполняться два часа, потому что из-за конструктивной особенности кода при расчете для каждого сотрудника проверка принадлежности к подразделению выполняется в среднем четыреста тысяч раз (другой пример из личной кунсткамеры автора). Это неприятно, конечно, но и только.
Гораздо хуже, когда носитель антипаттерна имеет довольно высокий уровень умения работать с платформой и получает возможность применить свой талант на больших проектах или, что гораздо опаснее, в тиражируемых продуктах. Ведь почти весь код почти всех тиражных продуктов открыт, и начинающие специалисты пытаются по этому открытому коду учиться. И когда опытный тимлид, проводя аудит, пытается поднять с пола упавшую туда челюсть, диалог с джуниором получается примерно таким:
— Сынок, <18+>, это кто тебя научил такое <18+> отливать в коде?
— Так вот же, дяденька, в <не будем показывать пальцем> точно так и сделано. Написал по образцу.
К сожалению, далеко не каждому джуниору везет попасть к опытному тимлиду. Как следствие, наиболее опасные антипаттерны разработки разносятся по сообществу, как вирусы, массово поражая молодые растущие организмы. Рассмотрим под микроскопом пару образчиков этой нечистой силы.
Спагетти
Рассказу о феномене спагетти-кода следует предпослать замечательное высказывание одного из отцов-основателей нашей отрасли по имени Эдгер ван Дейкстра:
— Компетентный программист полностью осознает строго ограниченные возможности своего мозга, поэтому подходит к задачам программирования со всей возможной скромностью.
Что же такое разработка в стиле спагетти (можно также назвать лапшой, солянкой, и даже ботвиньей)? Этот феномен можно определить, как локально переусложнённый и локально же нечитаемый программный код, в котором описывается множество перемешанных до полного непонимания разнородных сущностей, при грамотном подходе требующих строжайшего разграничения.
Можно и одним словом: месиво.
Нельзя сказать, что спагетти-код обязательно содержит ошибки или работает медленно. Такой код может быть почти идеально отлажен, может отвечать всем поставленным внешним требованиям, может выполнять поставленные задачи с высокой производительностью, и так далее. Тогда что же с ”лапшой” не так?
А вот что. Во-первых, такой код практически не поддается ни сопровождению, ни даже простому чтению. Во-вторых, обладает чудовищной трудоемкостью отладки и особенно локализации ошибок. И в-третьих, любое, даже совсем незначительное изменение или расширение требований почти в ста процентах случаев приводит к ситуации “проще это все переписать полностью, чем что-то здесь изменить”. Расширяемость “лапши” близка к нулевой.

Никого не напоминает этот трудящийся?
Памятка для самопроверки. Попробуйте поискать в своем коде следующие видовые признаки:
- Применение оператора GOTO (понятно, что этим оператором пугают детей, но все же).
- Процедуры и функции огромного размера, на несколько экранов.
- Многострочные блоки case (Если.. ИначеЕсли..), особенно с несколькими уровнями вложенности
- Обработка частных случаев, ломающих парадигму окружающего кода (например, добавление дополнительных условий вместо дополнительных значений переменной «состояние» конечного автомата).
- Общая неряшливость кода. Пренебрежение общепринятыми элементарными правилами форматирования и оформления.
- Укороченные и/или не имеющие смысла имена переменных.
- Отсутствие в коде внятных комментариев, начиная с заголовков процедур и функций.
Следует понимать, что каждый из приведенных признаков сам по себе не является абсолютным злом и при определенных обстоятельствах имеет право на существование (даже оператор GOTO, представьте себе). Но сколько-нибудь опытный разработчик всегда с первого же взгляда отличит, где вынужденное нарушение правил в человеческом коде, а где глубокая тарелка с ботвиньей.
Разберем простейший пример. Задача: в зависимости от неких внешних условий (состояние определенных объектов данных) выполнять определенные действия. Реализация в спагетти-стиле будет выглядеть примерно так:
- Единственная огромная функция СделатьВсеКакНадо(), двенадцать экранов длиной.
- Проверка внешних условий расположена внутри функции.
- Выбор действия реализован в формате многостраничного блока Если.. ИначеЕсли с тремя уровнями вложенности. Внутри каждой пары операторных скобок нижнего уровня расположен код, выполняющий действие. Причем действия принципиально разные, от “бросить исключение” до “прочитать и разобрать внешний файл данных”.
- Используется огромное количество переменных-флагов с ничего не говорящими (в лучшем случае) именами. В худшем случае это переменные вида ФлагОбработки23. В терминальном случае назначение переменной противоречит ее названию.
- Использование в case-блоке семантических конструкций вида Если Не НеДелать Тогда...
- Использование многоэтажных (от пяти и больше) условий И/ИЛИ в каждой ветке case-блока.
- Часть действий выполняется через Попытку, часть выполняется в транзакции. Операторные скобки попыток и транзакций перемешаны самым причудливым образом.
- Заворачивание некоторых (видимо, особо опасных) фрагментов кода в попытки без обработки исключений (“проглатывание исключения”).
- Функция решает несколько принципиально разных задач. По сути, это несколько функций, перемешанных в одну и имеющих некие общие фрагменты.
- Разумеется, никаких комментариев.
- Заголовок функции просто пересказывает ее название (“Функция делает все, как надо”). Описанные в заголовке параметры не соответствуют реальными ни по именам, ни по количеству.
В наиболее брутальном варианте разные фрагменты чудо-функции окажутся еще и написаны в разных стилях: часть по-китайски, часть по-индийски, ну и так далее.
Ничего не напоминает? Вот и автору тоже кое-что напомнило.
В чем же причина такого подхода к разработке со стороны многих и многих, казалось бы, квалифицированных (сертификаты на стене точно есть) разработчиков? Причины обычно самые банальные. У кого-то сложности с абстрактным мышлением, способностью проектировать сложные сущности и особенно их взаимодействие. Кому-то просто лень. А кто-то просто не знает, что можно разрабатывать программный код как-то по-другому.
Проблема спагетти-кода не в том, что код ужасен. Написание и особенно сопровождение такого кода требует очень существенных избыточных затрат, причем потери несет не только потребитель, но и разработчик. Это как подниматься на велосипеде в горку, для бодрости навесив себе на шею пару-тройку кирпичей.
Как избежать соблазна свалить все в одну неряшливую кучу и побыстрее покончить с задачей? Есть простой, но действенный принцип аутотренинга.
Программный код нужно писать так, как если бы дальнейшим сопровождением занимался агрессивный социопат, который точно знает, где вы живете.
Если соединить этот принцип с японской ментальной техникой “сегодня меня ждет...” и представить живую картину — сырой подвал, ржавая батаре
Вступайте в нашу телеграмм-группу Инфостарт