Все записи

Разбираем фичи по кусочкам: атомарные коммиты как внутренняя дисциплина

Дима руководит группой прикладной разработки в Naumen и много лет работает с командами, которые делают не одноразовые фичи, а долгоживущие системы — те, что развиваются годами, переживают смену людей, требований и контекста.

Дима.jpg

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


Что такое декомпозиция и почему с неё всё начинается

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

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


Зачем вообще декомпозировать задачи 

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

1. Это помогает при планировании

Пока задача выглядит как абстрактное «сделать фичу», планировать нечего. Как только появляются шаги, появляется и план.

2. Оценка по времени даётся гораздо проще

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

3. Руководство к действию для коллег

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

4. Параллельная работа в команде

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


Как декомпозиция приводит к модулям

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

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

Лучше всего это видно на примере.


Как выглядит декомпозиция на примере фичи

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

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

  • страница для ввода трек‑номера;

  • создание трек‑номера и присвоение его заказу;

  • поиск заказа по трек‑номеру в базе данных;

  • запись географического статуса курьера в базу данных;

  • отображение текущего положения курьера на карте.


Что меняется, если смотреть на задачу через бизнес-действия

Посмотрим на задачу не с точки зрения экранов и таблиц, а с точки зрения бизнес‑действий. 

Бизнес‑действие — это то, что наблюдаемо извне и имеет ценность для бизнеса. Это не «страница» и не «поле в базе», а конкретное действие системы.

Если переписать нашу задачу в этих терминах, получится такой список:

  • сгенерировать уникальный трек‑номер;

  • сохранить трек‑номер при создании заказа и вернуть его;

  • найти заказ по трек‑номеру;

  • получить текущее местоположение курьера;

  • сохранить местоположение курьера;

  • вернуть местоположение курьера по заказу.


Как из списка действий начинают проявляться модули

Следующий шаг — сгруппировать эти действия по смыслу. 

Про заказ:

  • сохранить трек‑номер при создании заказа и вернуть его

Про трек‑номер:

  • сгенерировать уникальный трек‑номер;

  • найти заказ по трек‑номеру

Про геолокацию курьера:

  • получить текущее местоположение курьера;

  • сохранить местоположение курьера;

  • выдать местоположение курьера по заказу

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

image2.png

Чёрным цветом обозначен существующий модуль, зелёным — новые модули

Дальше всё действительно зависит от контекста: где провести границы и насколько сильно дробить. Например:
  • хранить ли трек‑номер прямо в заказе или вынести трекинг в отдельную модель;

  • делать ли отдельную таблицу или даже отдельную базу данных;

  • насколько мелко дробить систему.

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

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

image1.png

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

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


Что такое атомарный коммит

Атомарный коммит — это самостоятельный кусочек логики, который можно понять отдельно от общей логики. Один коммит — одна идея.


Почему атомарные коммиты упрощают работу с кодом и историей

Атомарные коммиты приносят очевидную пользу: легко откатывать изменения, переносить между ветками, ревьюить, находить «плохие» коммиты с помощью git bisect.

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


Как атомарные коммиты тренируют навык декомпозиции

Но есть менее очевидный, но очень важный аспект: атомарные коммиты тренируют навык декомпозиции.

Чтобы написать задачу серией атомарных коммитов, разработчику приходится каждый раз отвечать на вопрос: «Что здесь является отдельным, законченным шагом?». Это и есть декомпозиция. 

На практике я вижу две основные проблемы:

  • git является сложным инструментом, с которым трудно перейти «на ты»;

  • дробить большую задачу на маленькие шаги — сложная задача сама по себе.

Атомарные коммиты решают вторую проблему через регулярную практику. Повторение работает лучше любых теорий.


Как писать атомарные коммиты на практике

Всё сводится к очень простому процессу:

  1. Декомпозиция. Хотя бы мысленно расписываем по шагам, как будет решаться задача.

  2. Группировка кода. В один коммит попадает то, что решает одну логическую задачу и изменяется вместе. Например, тесты + реализация или отдельно модуль + отдельно его использование.


Что делать с правками и ревью

Частый страх: «Я выстрою красивую цепочку коммитов, а потом придётся всё переделывать». Если важна чистая история, используйте:
  • git commit ‑fixup <my‑bad‑commit‑hash>

  • git rebase ‑interactive ‑autosquash master

Если история не критична — просто добавляйте новые коммиты. Ничего страшного. 


Как понять, что коммит атомарный

Чёткого критерия нет — все зависит от контекста.

Но есть простой лайфхак: если название звучит как «X и Y», скорее всего, это два разных коммита. Например: «Создание трек‑номера и присвоение его заказу».

Лучше сделать так:

  • «Создание трек‑номера»

  • «Присвоение трек‑номера заказу»


Какие выводы можно из этого сделать

Декомпозиция важна не только для планирования и оценки задач — она помогает проектировать архитектуру и выделять модули.

Атомарные коммиты — это не просто аккуратная история в git. Это доступный способ тренировать навык декомпозиции каждый день.

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

Похожие новости

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

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

Делимся советами и рассказываем на кейсах, как «правильно» принимать обратную связь.

Как освоить ИИ и сделать его частью повседневной работы

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

Мифы о тестировании

Диана работает тестировщиком больше полутора лет. Когда она только приходила в профессию, ее представления складывались из статей, курсов и разговоров с друзьями из ИТ. Казалось, что работа у тестировщика довольно простая: технических знаний нужно немного, а зона ответственности ограничена.

Практика быстро показала, что это не так. В статье Диана собрала мифы о тестировании, в которые верила, и то, как все оказалось на самом деле.

Все новости