Это несерьёзная статья на серьёзную тему. Есть такое понятие, как JSDD — Job Safety (Security) Driven Development, мы часто видим его в крупных компаниях. От этого не избавлены и небольшие компании, особенно когда в штате всего несколько программистов. Разработчики пишут свой код столь изысканным способом, что, несмотря на очень низкую скорость разработки, их страшно уволить, потому что, кроме них, этот код никто понять не сможет. Давайте попробуем разобрать, почему и как такое происходит.

Меня зовут Константин Митин, я сооснователь и руководитель компании АйТи Мегастар/АйТи Мегагруп. Когда-то был простым разработчиком, работал в L3, дорос до тимлида, затем и до руководителя филиала разработки крупной ИТ-компании. Теперь я в АйТи Мегагруп.

Предыстория появления подхода

В разработке программного обеспечения есть много полезных инструментов и методологий. Например, когда я сам писал код, мне нравилось использовать TDD (Test Driven Development). Это разработка через тестирование, когда ты сначала пишешь тесты для своего функционала, а потом реализуешь сам функционал. Затем дорабатываешь тесты, следом дорабатываешь функционал.

Помните выбор между быстро, качественно и недорого? На самом деле, делать качественно — быстрее и дешевле, потому что ты выпускаешь меньше брака. TDD даёт именно такой эффект. Кому-то может показаться странным, но большую часть рабочего времени программист думает, а не набирает код. Большинство программистов не обладает навыками слепой печати просто потому, что разработку этот навык никак не ускоряет.

Делать качественно — быстрее и дешевле. Ты меньше ошибаешься и меньше тратишь время на исправление ошибок.

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

Мне часто приходилось работать с чужим и уставшим кодом. Видел я при этом всякое. Иногда это был уже не рефакторинг, а реинжиниринг кода. В таких случаях написать тесты для заменяемого функционала, чтобы сохранить обратную совместимость, просто необходимо в целях безопасности. Заодно, пока пишешь тесты, исследуешь заменяемый функционал, понимаешь, как и почему именно так он работает, находишь в нём ошибки и принимаешь решение по их исправлению. Именно принимаешь решение исправлять ошибку либо придётся писать имитатор ошибки, как это было сделано в Win98 для сохранения обратной совместимости с Win95. Иногда исправить ошибку в месте, над которым работаешь — это обрушить целый модуль на другом краю приложения, потому что код изобилует костылями. И никто не рассчитывал, что всё внезапно заработает.

В результате получался понятный, самодокументируемый код со встроенными средствами самопроверки. То есть меня могли легко уволить и отдать код другому разработчику, он бы в нём быстро разобрался. Это важный момент.

Bus factor — количество ключевых специалистов, после потери которых работа не сможет продолжаться.

Есть такое понятие, как «bus factor». Представьте, что ваш ключевой сотрудник выходит из офиса и его насмерть сбивает автобус. Что дальше? Этот вопрос всегда держит в голове хороший разработчик и руководитель проекта. Мы должны быть взаимозаменяемыми.

Кроме TDD есть ещё BDD (Behavior Driven Development), FDD (Feature driven development) и другие виды xDD.

Job Safety Driven Development

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

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

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

Либо просто уже хочется стабильной работы и надёжного источника пропитания для себя и своей семьи. В наше время постоянно появляются новые технологии, методологии, надо быстро учиться, чтобы не отстать и не остаться за бортом. А тут уже и возраст подходит. Возникает потребность в «Job Safety».

На помощь приходит методология JSDD (Job Safety Driven Development), его сторонники прикладывают максимум усилий, чтобы стабильность их положения ничто не могло поколебать. А для этого нужно, чтобы bus factor был равен 1.

Знаете, когда-то был термин «индусский код»? Когда-то много индусских программистов работало на аутсорс и платили им за строчки кода. Ну ребята сразу научились делать простое сложным и писать тысячи строк вместо одной-двух. Работать с таким кодом — изысканное удовольствие, если конечно ты не разработчик с построчной оплатой кода. С JSDD так же.

Как и в любой методологии в JSDD есть best practices и принципы. Давайте познакомимся с ними поближе. Иногда будет казаться, что они несовместимы, но JSDD действительно может их подружить между собой.

Простое должно стать «rocket science»

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

Желательно говорить сложным языком, применять как можно больше технических терминов и жаргонизмов. Часто бизнес просто не готов говорить на «птичьем языке», который разработали программисты, чтобы их не понимали. Пользуйтесь этим.

Например, у вас есть сервис, написанный на Django, с базой данных в виде SQLite, который посещает 10 человек в месяц. К вам приходят и спрашивают: «Сколько будет добавить поле в таблицу?». Вы должны сказать, что из-за нагруженности системы это сделать будет непросто, нужно будет написать миграцию для базы данных, провести полное регрессионное тестирование, обеспечить даунтайм в день для того, чтобы все смогло развернуться. Плюс ко всему, в сервисе реализована подсистема работы с кластерными базами данных, обеспечивающая отказоустойчивость в момент, когда кластер баз данных отказал, причём с двумя слоями кеширования запросов, потому что кластер Redis тоже может отказать. Кроме того, у вас там развитая система логирования, которая в том числе обеспечивает логирование всех транзакций, чтобы можно было в случае отказа кластера базы данных, кластера кеширования, кеширования в ОЗУ, восстановить данные по логу транзакций. Работа предстоит сложная и займёт 1-2 месяца. Запомните, сложную работу нельзя сделать быстро.

Надеюсь, разработчики юмор оценили. Для бизнеса же скажу, что это всё вообще не нужно и можно всё сделать за 1-2 часа работы вместе с внедрением и всеми проверками.

Запомните, сложную работу нельзя сделать быстро. Любую работу можно сделать сложной.

Не оставляй следов

Вы должны научиться не оставлять за собой следов. Прежде всего это относится к документации. Её категорически нельзя писать, делайте всё, что угодно. Лучше всего ссылаться на практики Agile, ведь работающий продукт важнее документации? Если вас загнали в угол, то закатывайте глаза и давайте оценку на документацию в виде «овердофига».

Помните, что сложную работу — нельзя сделать быстро. А вам предстоит потрудиться. Нужно создать объёмную и запутанную документацию, которую никто не будет читать. Можно даже описывать всё, как есть. Всё равно вы не будете её обновлять. У вас не должно быть на это времени.

Точно так же с постановками задач. Из них бизнесу не должно быть понятно, что и зачем вы делаете. Никогда не пишите задачи на человекопонятном языке. Лучше всего используйте в описании задачи мета-код и обязательно запросите время на исследование. Потом создайте десятки подзадач с оценками в 1-2 часа.

Запомните, для сложной работы просто так постановку задач не сделать. Это сложно, а сложную работу — нельзя сделать быстро.

Никакой документации и внятной постановки задач. Сопротивляйтесь до последнего.

Переусложнение архитектуры

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

Теперь надо это реализовать. Я серьёзно. Мы должны сделать простое сложным. Поэтому мы будем удовлетворять свои амбиции и реально напишем подсистему для работы с кластерным SQLite и двухслойную систему кеширования данных, плюс систему логирования и восстановления по логу транзакций. Заодно ещё и отдельный ELK под это дело развернём. Главное самому не запутаться.

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

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

Если вы увлеклись, начали не спать и работать по ночам и выходным, то подавайте это как вовлеченность и лояльность к компании.

Оверинжиниринг

Кроме сложной архитектуры, для решения простой проблемы, нам понадобится ещё и техническое переусложнение (оверинжиниринг) на уровне кода. Нужно написать много кода. Это значит, что нужно подойти к коду как перфекционист. Код должен быть идеальным, используйте все лучшие практики.

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

Кроме того, обязательно, слышите, обязательно используйте паттерны проектирования. Во-первых, их очень много. Во-вторых, бизнес всех их названий не запомнит, а названия звучат круто, и не важно, что вы использовали паттерн не по назначению. Книга «Банда четырёх» про паттерны программирования — большая и сложная. Чтобы её понять, даже профессионал читает её на несколько раз. Бизнес её читать точно не будет.

Помните, что если можно сделать что-то простое сложным, то сделайте это. Сложным должен быть не только ваш код, вся ваша работа должна выглядеть сложной.

Сложным должен быть не только ваш код, вся ваша работа должна выглядеть сложной.

Слепое следование стереотипам

В мире информационных технологий очень много полезных инструментов и подходов. Их нужно использовать, но как это совместить с JSDD? Всё просто. Не пользуйтесь первоисточниками. Не надо разбираться в том, какие идеи изначально вкладывались в рефакторинг Фаулера, паттерны проектирования «Банды четырёх» и прочего. Вам нужны инфоцыгане. После нескольких итераций перепечатки без понимания даже очень хороший подход станет пригоден для JSDD.

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

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

Также не стоит слепо следовать всем стереотипам. Иногда на рынок заходит что-то очень полезное и действенное, важно этим случайно не воспользоваться. Выработайте «туннельное зрение», возведите в культ только избранный набор стереотипов и закройтесь от всего нового.

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

Никакой обратной совместимости

Внимание! Важно. Вы должны постоянно переписывать и дописывать функционал. Теряйте обратную совместимость, это полезно. Потом закроете проблему костылями.

В идеале вам следует написать первый слой API. Потом начать писать вторую версию API, бросить её на полпути, начать писать третью версию API, включая туда новые методы. Методы в первой, второй и третьей версиях API должны ссылаться друг на друга. Обещайте всё исправить в четвёртой новой версии API, в которой будут только новые методы API.

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

Сделай несколько недописанных API, которые перекрестно используют функционал друг друга.

Велосипедостроение и инновации

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

При этом нужны и велосипеды. Прямо в ядре того, чем вы занимаетесь. Идеально написать свой фреймворк, вокруг которого развешать инновационные микросервисы. Даже если кто-то уже 1000 раз решал какую-то задачу до вас, то ваше 1001 индивидуальное решение всё равно необходимо миру. Ведь у вас получится лучше. Ведь если бы вы не сидели в своей компании, а, например, запускали бы людей на Марс, то люди бы уже летели на Альфа-Центавру.

Даже если кто-то уже 1000 раз решал какую-то задачу до вас, то ваше 1001 индивидуальное решение всё равно необходимо миру.

Индивидуальная разработка

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

Классной идеей является ввод код-ревью. С помощью него можно останавливать работу особо инициативных и продвинутых. А ещё можно совместно работать с собратом по JSDD, переправляя и усложняя код друг друга. Кроме того, код-ревью удлиняет работу, а вы делаете сложную работу, сложную работу — нельзя сделать быстро. И код-ревью даёт видимость сложности, под него даже можно сделать особый процесс с приёмом мёрж-реквестов по пятницам. Заодно возникнут конфликты с коммитами, и весь понедельник можно тратить на их разбор.

Можно сделать особый процесс с приёмом мёрж-реквестов по пятницам. Заодно возникнут конфликты с коммитами, и весь понедельник можно тратить на их разбор.

Непредсказуемость

В вашей работе должно быть всё непредсказуемо и сложно. Старайтесь не давать конкретных сроков и оценок, ведь в вашей работе кроме сложности есть большая степень неопределённости. А если дали чёткую оценку — сорвите её, выдайте длинное объяснение, почему такое произошло, и опишите то, что предсказать было невозможно.

Идеально для затягивания сроков подходит багфикс. Давайте оценку на разработку без учёта отладки и багфикса. Лучше всего разрабатывать через багфикс. Тогда вы, наоборот, занижаете оценку, пишите что-то не проверяя, а потом тратьте х10 времени на исправление багов. Заодно и вашего QC не уволят. Регресс очень важен для JSDD. Все должны понимать, что без вас всё сломается и никто, кроме вас, не сможет это починить.

Важный момент. Никогда не заканчивай. Работа всегда должна оставаться немного незавершённой. По объективным причинам. Это создаёт необходимую суету в разработке и держит заказчика работы в напряжении. Должно быть интересно не только тестировщику, но ещё и заказчику.

Идеально для затягивания сроков подходит багфикс.

Стань супер-героем и спаси всех

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

Желательно, чтобы в момент падения, система использовалась бизнесом. Они должны заметить падение системы и ощутить полную меру ужаса происходящего и свою беспомощность. Рассчитайте момент таким образом, чтобы вас не было на рабочем месте. Лучше всего, чтобы вы были в отпуске и в отдалённом месте с одним телефоном, без компьютера. Почему?

Потому что, когда вам будут в панике звонить, вы сможете описать, как вы сейчас сидите с удочкой на отдалённом горном озере и сейчас вам очень сложно будет что-то сделать. После чего вы скажете, что сейчас попробуете исправить всё с телефона (!!!). Для этого включаем VPN на телефоне, получаем консольный доступ к серверу. Нет, я не шучу, были реальные случаи, когда так приходилось делать. И через консоль на телефоне — поднимаете сервер. Желательно, минут за 10 до того, как ответственные люди должны предстать перед генеральным директором организации.

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

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

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

Подводя итоги

Принципов и best practices в Job Safety Driven Development гораздо больше, чем я смог описать, например, есть еще адаптация JSDD под Agile. Всё же это лишь несерьёзная статья на серьёзную тему. Она призвана только подсветить проблему, пусть даже в виде шутки.

Возможно, я когда-нибудь напишу про JSDD уже серьёзно. Мы иногда проводим ИТ-аудит, при котором встречается разное. Часть случаев списана с реальных событий, происходивших в компаниях наших заказчиков, да и в нашей собственной компании тоже. На самом деле, доля шутки в том, что я написал выше, не такая уж и большая.

Давайте напоследок выделим главное в Job Safety Driven Development:

  • Bus factor сотрудника стремится к единице.
  • Сотрудник не может либо не хочет говорить на понятном всем языке. Поверьте, «птичий язык» в области информационных технологий не является чем-то обязательным.
  • Работа сотрудника носит непредсказуемый и непонятный характер, вокруг него всегда много суеты.
  • Создаётся видимость высоких рисков для бизнеса. Важность многих проблем сильно преувеличивается.

Конечно, можно выделить ещё что-нибудь, но пора заканчивать. Если вы дочитали до конца, вам было интересно и забавно, то спасибо вам. Если вы поняли для себя что-то важное, то спасибо вам вдвойне.