Marat Khusainov
Разработка

Как я перестал теряться перед большой задачей

6 мин чтения

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

Симптомы

Если узнаёте себя, знаком случай:

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

Это не лень. Это когнитивная перегрузка. Голова пытается одновременно держать в фокусе цель, архитектуру, синтаксис, имена, граничные случаи. На каждое из этого нужны ресурсы, и когда всё разом, мозг просто отказывает.

Цитата, которая меня зацепила

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

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

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

Чтобы работать руками быстро, нужно перестать залипать. Здесь и появляется декомпозиция.

Метод

Звучит банально, поэтому я его долго игнорировал.

Перед тем как открыть редактор, я открываю заметку и пишу шаги.

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

Шаги пишу до того момента, когда они становятся слишком очевидными. Вот критерий остановки. Если следующий шаг звучит как «вызвать функцию X с такими-то параметрами», значит, дальше расписывать не надо. Дальше начинается работа в коде.

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

Через 15-30 минут декомпозиции я понимаю задачу принципиально лучше. И к коду подхожу уже с конкретным первым шагом, а не с вопросом «откуда вообще начать».

Пример из реального проекта

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

Сначала я бы открыл новый файл OnboardingViewModel.swift и начал бы писать класс. И залип бы на второй строчке.

Вместо этого я открыл заметку и написал:

  1. Описать структуру: одна группа вопросов, набор Question, каждый вопрос с типом ответа и весом
  2. Решить, как хранить промежуточный ответ. В памяти ViewModel или в Core Data
  3. Параметры пользователя, которые мы считаем по ответам: норма калорий, типичный режим, уровень мотивации. Где описаны эти формулы?
  4. Скоринг. Каждый ответ имеет вес, в конце группы суммируем, привязываем к параметру
  5. Динамические блокеры. Некоторые ответы должны блокировать следующие вопросы (пример: «нет аллергий», пропускаем блок про аллергены)
  6. Выход из онбординга. Куда уходим, что сохраняем
  7. Persisting. Что лежит в Firestore (event-driven, см. архитектуру проекта), что лежит локально
  8. Тесты. Какие edge cases важны: пропуск ответа, ответ-исключение, возврат на предыдущий шаг

Когда я это написал, стало видно три вещи:

  • Структуру Question лучше делать перечислением (enum) с associated values по типу ответа
  • Формулы скоринга я не знаю, это вопрос к клиенту, не моё дело его выдумывать
  • Динамические блокеры это отдельная задача с независимой логикой, её лучше вынести в отдельный сервис

После этого я сделал две вещи. Отправил вопрос про формулы клиенту и сел писать код. Первые два часа улетели на структуру Question и Answer плюс простой роутинг по вопросам. К концу первого дня у меня был работающий онбординг на статичных тестовых данных. Без блокеров, без скоринга, но работающий каркас.

Если бы я начал «как обычно», я бы первые два часа потратил на размышления, потом сделал бы класс с ответами в виде словаря строк, потом полез бы рефакторить. И к концу дня была бы половина того, что есть сейчас.

Когда декомпозиция не нужна

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

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

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

Про оценку времени

Тот же метод используется для оценки сроков клиенту. Без декомпозиции я говорю «три дня» и почти всегда это враньё. С декомпозицией я смотрю на свой список из 8-15 пунктов, оцениваю каждый в часах, складываю, умножаю на 1.5 (потому что забыл что-то), и получаю честную оценку.

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

Что взять отсюда

Если у вас бывает ступор перед задачей, попробуйте простое:

  1. Закройте редактор кода. Откройте текстовую заметку.
  2. Запишите цель одной строкой: что должно быть в результате.
  3. Распишите 8-15 шагов до момента, когда следующий шаг это «открой файл и напиши X».
  4. По ходу записи помечайте вопросы и неизвестные отдельными пунктами.
  5. Когда список готов, отправьте вопросы тому, кто может ответить (клиент, тимлид, документация). Не блокируйтесь на них, начинайте с независимых пунктов.
  6. Открывайте редактор и работайте по списку.

Через пять задач, сделанных по такому процессу, вы перестанете залипать. Через двадцать научитесь оценивать сроки честнее, чем 80% разработчиков, которые «оценивают на глаз».

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

Что дальше

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

Похожие статьи