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

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

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

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

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

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

А вот про реализацию девушки сказать особо нечего. «Реализовала фичу X». Всего три слова. Хотя её работа была лучше. Но в свете минимализма и простоты заметить это сложно. Нельзя убедительно расписать то, что ты не создавал. Поэтому никого не повышают за то, что он избежал лишней сложности.

Возьмём, к примеру, собеседования. Представьте, что находитесь на этапе проектирования системы и предлагаете простое решение. Одна база данных, простой API и, быть может, дополнительный уровень кэширования. Рекрутёр задаёт вопрос: «А как же масштабируемость? Что, если у вас будет десять миллионов пользователей?» Тогда вы начинаете рисовать на доске больше блоков, добавляя сервисы, очереди и реализуя шардинг БД. Вот теперь рекрутёр доволен.

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

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

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

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

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

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

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

Но что мы реально предпринимаем по этому поводу? Одно дело сказать «не усложняй», и совсем другое — изменить систему мотивации.

Если вы разработчик

Запомните — простота должна быть заметной. Работа не говорит сама за себя. И дело не в том, что она недостаточно хороша, а в том, что большинство систем поощрения не способны её «услышать».

Начните с подачи. «Реализовал фичу X» мало что говорит. А вот «Проанализировал три решения, включая событийно-ориентированную архитектуру и собственный уровень абстракции. Решил, что простая реализация отвечает всем текущим и прогнозируемым требованиям. В итоге за два дня реализовал решение, в котором за шесть месяцев не возникло ни одной проблемы». Это описание всё той же простой работы, но уже с выражением стоящих за ней рассуждений. Решение не создавать что-либо — это тоже решение, причём важное! Так что описывайте его должным образом.

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

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

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

Если вы руководитель

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

Поэтому старайтесь изменить постановку вопроса, и на дизайн-ревью вместо «А мы учли возможность масштабирования?» спросите: «Как будет выглядеть простейший вариант фичи, и какие сигналы укажут на необходимость чего-то более сложного?» Один только этот вопрос уже изменит правила игры, поставив во главу угла простоту и потребовав обоснования сложного решения — а не наоборот.

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

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

В конечном итоге, если мы продолжим поощрять сложность и игнорировать простоту, то можно будет не удивляться, что сложность мы и получим. Но исправить это нетрудно. О чём, собственно, и речь.