Когда последовательность важнее правильности

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

Представьте ситуацию: приходит задача дополнить валидацию данных пользователя, которую писали до вас. Вы открываете код и видите:

const validateUserData = (userData) => {
  const {socialNumber, email} = userData
  return validateSocialNumber(socialNumber)
    || validateEmail(email)
}

Вы знаете, что все поля обязательные, и вам непонятно, почему возвращается истина если валидно хотя бы одно значение, а не всё вместе.

Вы открываете код функций validateSocialNumber и validateEmail и видите, что они возвращают истину, если в данных есть ошибка. Откуда делаете вывод, что и validateUserData возвращает истину, если есть ошибка (наверное, на то были причины ¯\_(ツ)_/¯). Беглый просмотр кодовой базы показал, что таких функций много, они встречаются в разных модулях, и быстро исправить всё не получится.

Ваша задача — добавить проверку почты и сделать это «ВЧЕРА!!!». Из‑за сроков отрефактироить код перед этим не успевается (напомню, подобных функций много). Вы понимаете, что правильнее — написать новую функцию так, чтобы она возвращала истину, если ошибок нет…

Но прямо сейчас последовательность — важнее правильности, и первый шаг — сделать по аналогии, сделать «неправильно»

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

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

Болеть за продукт

Я, наверное, невероятно очевидную вещь сейчас скажу, но очень надо, ужизвинити.

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

Без веры в продукт задачи становятся просто какими‑то штуками, работать с которыми скучно, неинтересно, субъективно бессмысленно. Чё‑то там сбоку происходит, ну и ладно.

С ней же задачи — это боль пользователей, которую видно и которая зудит. От этого зуда и появляется желание поправить баги, обкатать фичу, проверить гипотезу.

Но что делать, если не получается болеть?

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

А можно устать от продукта. Так бывает, люди меняются, всё нормально. Осознайте, насколько сильно просели мотивация и польза (вам и от вас) и примите решение, что делать дальше.

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

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

P.S. Я сейчас не говорю об аспектах, связанных с командой, комьютом, офисом, плюшками и проч. Речь именно о том, над чем вы работаете.

P.P.S. Примерно о том же, но гораздо подробнее, я писал во «Фронтенд — это не больно!».

Не надо заставлять

В эфире рубрика «Лайфаки от капитана Очевидности». Рассказываю, чё делать, если не получается себя заставить чё‑то делать.

— Когда не получается заставить себя чё‑то сделать, не надо заставлять себя это делать.
— Спасибо, Кэп!

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

На примере, пожалуйста

Кулстори из прошлого. Когда‑то давно, ещё до того, как я придумал себе нормальную систему деления рабочего времени, я не мог заставить себя делать перерывы.

Пробовал помидорки, но они не работали. Я откладывал отдых, забивал на перерывы и обнаруживал себя проработавшим 14 часов подряд. А потом пытался понять, чо ж было не так.

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

Появилась идея, что неплохо бы отдать контроль за выполнением уговора куда‑то вовне. Поставил себе программу, которая блокирует компьютер через определённые интервалы времени. Она предупреждала за 5 минут, а потом блокировала всё нафиг: останавливалась музыка, гас монитор, компьютер переставал реагировать на клавиатуру и мышь.

Мне ничего больше не оставалось, как встать из‑за стола и поделать что‑то ещё, потому что иначе — скучно. То есть я не мог не выполнить уговор с собой, потому что не было возможности не выполнить его :–)

Радикально как‑то

Ну да! Но такой способ даёт понять, действительно ли мне так важна эта хрень, которую я не могу заставить себя сделать. Если нет, то ну и зачем она мне?

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

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

Другие о том же

Бесценный обесцененный опыт

Пришёл домой от терапевта, а значит настало время для ещё одного поста ¯\_(ツ)_/¯
Сегодня расскажу о вреде обесценивания прошлого опыта. Приготовьте там чаю себе, пост длинный.

О чём в этот раз

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

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

Почему это вредно

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

Когда я обесцениваю прошлый опыт, я лишаю себя опоры и перестаю понимать, как относиться к ситуации

Без опыта нет ориентиров. Становится непонятно, куда мне хочется двигаться и как я себя вижу в этом мире. Я как будто отформатированная флешка, во мне ничего ещё нет.

Обесценивание заслуг вызывает страхи, что всё, что я сделал — не по‑настоящему. Что в один момент это раскроется, и все поймут, что я ничего не умею и абсолютно бесполезен. Неважно: связано с работой, лично жизнью или чем‑то ещё.

Только разница с чистой флешкой в том, что на ней и страхов тоже нет. Она не боится сделать ошибку, а я в таком состоянии — боюсь.

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

Давай‑ка на примере

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

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

Чувствуете, как быстро дошло до абсурда?

Только снаружи абсурд видно, а изнутри — нет. Изнутри всё получается как‑то стройно, логично и вообще — начинаю себе верить.

Откуда берётся этот голос

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

Так вот. Личность состоит из множества субличностей, которые как‑то пытаются друг с другом коммуницировать. Об этом писал Курпатов в «Красной таблетке», где приводил пример, как поведение людей меняется в зависимости оттого, находятся они рядом со своими родителями или детьми. Разный контекст — разные модели поведения.

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

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

Когда между ними возникает конфликт интересов, скрытая субличность пытается обратить на себя внимание, чтобы что‑то рассказать и объяснить. А самый удобный механизм для этого — обратиться к воспоминаниям или опыту и использовать их.

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

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

Что советует терапевт

Надо учиться слышать этот голос не как голос страха, ужаса, стыда и прочих ништяков, а как голос критика, который пытается донести мнение со стороны. Для этого мне посоветовали несколько вещей.

Проговаривать страхи вслух

Раз абсурд заметно со стороны, надо слушать себя со стороны. Я уже как‑то писал об этом в посте о неправильных выводах.

Вообще проговаривать вслух всё подряд очень помогает. Мысль слишком быстрая штука, чтобы успеть её как‑то обдумать. Слова или текст гораздо медленнее, и пока я проговариваю или записываю что‑то, успеваю несколько раз обдумать мысль.

На ней как бы появляется больше слоёв, из‑за чего она становится более конкретной. Это и помогает найти изъяны.

Осознать свою полезность в прошлом

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

Когда начинается телега с обесцениванием — освежать в памяти эти моменты. Важно: они должны быть мощными, чтобы убедить меня, иначе они тоже обесценятся.

Осознать свою полезность в настоящем

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

Мне нужно определить, кому и как я приношу пользу сейчас. Опять же это должно быть чем‑то мощным, чтобы иметь эффект.

Определить, что пытается донести критик

Голос не возникает просто так, для этого обычно есть предпосылки. Критику что‑то не нравится в этой жизни, он пытается об этом сказать. Моя задача — определить, что именно не нравится и почему.

Найти способ коммуникации

Чтобы найти причины недовольства критика, надо найти способ с ним общаться.

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

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

Этот символ будет переключателем, который будет давать скрытой субличности «выйти в свет» и сказать, что хочется. У меня это происходит (опять, лол) через заметки в телефоне.

Звучит как какая‑то дичь

Да я и не отрицаю.

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

Почитать на тему

Грязная архитектура

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

Проблема

Современный фронтенд — сложный. Много бизнес‑логики перекочевало из сервера в браузер. Сингл‑пейджи, большие приложения со сложной структурой, логикой и прочим — этим добром сейчас никого не удивишь.

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

Ну и сроки, да. Они всегда горят. Разработчики стали той собакой, у которой «всё хорошо»:

Появились инструменты для решения проблем с рутиной. Манипуляции с ДОМ, запросы к серверу, обработка состояния, хранение данных — со всем этим нам стали помогать библиотеки и фреймворки.

Инструменты — это суперздорово, потому что они снимают с разработчиков нагрузку и позволяют сосредоточиться на бизнес‑логике приложения. Хорошо же? Да, хорошо, но только это чё‑то не работает, как задумано.

Мы всё ещё не уделяем достаточно внимания бизнес‑логике, а упарываемся по модным библиотекам (привет, Реакт!) и фреймворкам (привет, Ангуляр!). И спорим, что лучше, что хуже, на чём приложения моднее.

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

Инструмент не должен вообще ничего вам диктовать

Инструмент должен делать работу, для которой его придумали. Молоток не говорит плотнику, как ему сколачивать детали друг с другом, потому что плотник использует молоток как подручное средство.

Не должно быть никаких «Реакт‑приложений» или «Редакс‑приложений», потому что это инструменты. Реакт должен рисовать пиксели на экране. Редакс должен работать с состоянием. Всё.

А как надо, умник?

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

Бизнес‑правила — скелет, вокруг которого наворачивается мясо

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

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

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

При грамотно спроектированной архитектуре приложения, вы можете выкинуть Реакт и переписать всё за вечер на Вью. И приложение не поломается, потому что интерфейс зависит от бизнес‑правил, а не наоборот.

А как же фигак‑фигак и в продакшен?

Ну да, есть такое. Сроки горят, прототипы нинужны, на тесты нет времени. Плавали, знаем.

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

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

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

Ну и как тогда начать проект?

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

Но за меня на этот вопрос уже ответил Дэн Абрамов в твитере:

Всё зависит от бизнес‑правил. Проектируйте, опираясь на них

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

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

Ссылки

Конспект «Чистой архитектуры»

Дэн Абрамов в твитере

Раньше ↓