Перейти к основному содержимому

Архитектура и организация кода

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

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

Что нужно понимать

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

Основные темы

Ответственность и границы

Единица кода делает одну вещь и честно её называет.

  • Единственная ответственность — на практике, а не как лозунг
  • Публичная поверхность против внутренностей
  • Сколько должен стоить переход через границу

Зависимости

Направление важнее количества.

  • Направление зависимостей и почему оно должно быть односторонним
  • Инверсия — зависеть от интерфейса, а не от реализации
  • Циклы и почему они первый признак того, что где-то не хватает границы

Структура

  • Feature-first против layer-first и что каждый из подходов оптимизирует
  • Где живёт общий код и в какой момент «общее» превращается в свалку
  • Границы модулей и пакетов как запрет, а не как пожелание

Сдержанность

Принципы, которые действительно стоит применять.

  • KISS — самое простое решение, которое переживёт следующее изменение
  • DRY — и куда более частая ошибка: применять его к вещам, которые лишь внешне похожи
  • YAGNI — абстракция под будущее, которое так и не наступает

Уровни

УровеньКак это выглядит
JuniorСледует существующей структуре. Кладёт новый код туда, где уже лежит похожий.
MiddleЗамечает, что у файла или фичи выросло две ответственности, и разделяет их. Спорит о направлении зависимостей с аргументами.
SeniorЗадаёт структуру новой кодовой базы и может сказать, что она оптимизирует и чем жертвует. Знает, какие решения стоит отложить.

Практика

Для начала

  • Назовите ответственность Возьмите файл длиннее трёхсот строк и напишите одно предложение о том, зачем он нужен. Если понадобилось «и», разделите файл.

  • Проследите зависимость Выберите фичу и нарисуйте, что она импортирует. Поищите то, что смотрит не в ту сторону.

  • Удалите абстракцию Найдите интерфейс ровно с одной реализацией и вставьте реализацию на место. Посмотрите, стало ли хоть где-нибудь хуже.

Дальше

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

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

  • Запишите правило Превратите договорённость, которую команда раз за разом повторяет на code review, в проверку, которую делает инструмент.

Проверьте себя

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

Ресурсы

  • A Philosophy of Software Design — Джон Оустерхаут о сложности как о том, с чем на самом деле идёт борьба. Короткая книга с чёткой позицией, спорящая с несколькими вещами, которые все повторяют.
  • Martin Fowler on software architecture — собрание эссе, в том числе о том, что вообще значит слово «архитектура» и почему за неё стоит платить. Начинать стоит с Who Needs an Architect?
  • Refactoring — каталог того, как безопасно менять структуру. Ценность не столько в отдельных приёмах, сколько в привычке менять форму кода маленькими обратимыми шагами.
  • Domain-Driven Design Reference — сжатая выжимка от самого Эрика Эванса, бесплатно. Полезна, даже если вы никогда не возьмёте DDD целиком: ограниченные контексты — самое внятное объяснение того, зачем вообще нужны границы.
  • Guide to app architecture — взгляд самой команды Flutter. Его стоит прочитать именно потому, что он высказывается о конкретном стеке, а не о разработке вообще.