К содержимому
МАТЕРИАЛЫ КУРСА
НАВИГАЦИЯ

Абстракции: чаще убрать, чем добавить

Почему «не идёт» означает разошедшуюся модель предметной области и почему слой чаще нужно убрать, чем добавить

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

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

Признаки лишнего слоя

Их видно глазами, без метрик:

  • Слой, который только прокидывает вызовы. Метод принимает те же аргументы, что и вызываемый, и возвращает тот же результат. Единственное, что он добавляет, — ещё один файл в стектрейсе.
  • Интерфейс с единственной реализацией. Заведён «на случай, если появится вторая». Второй за семестр так и не появится, а читать код через лишний прыжок будете все шестнадцать недель.
  • Абстракция названа по технологии, а не по смыслу. DatabaseManager, APIHandler, ServiceWrapper — имя, которое ничего не говорит о предметной области, обычно означает, что за ним и нет никакой предметной области.
  • Правка в одном сценарии задевает три модуля. Границы нарезаны не по линиям изменений, а по слоям технологии.

Два признака вместе — повод присмотреться. Три — почти диагноз.

Что изменила агентная разработка

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

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

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

Как это проверяет машина

Ощущение «стало запутанно» — не аргумент в споре. Аргумент — цифры aact analyze:

  • cohesion ниже единицы у границы означает, что внутренних связей меньше, чем внешних: компоненты внутри границы связаны друг с другом слабее, чем с тем, что снаружи. Граница проведена не там.
  • правило commonReuse ловит модуль, который тянут ради половины содержимого, — кандидат на разделение.
  • acyclic ловит цикл: A знает про B, B знает про A. Это всегда разошедшаяся модель, а не «так исторически сложилось».

Дальше работает обычный порядок: увидели цифру, поменяли границы, зафиксировали решение с ценой в ADR. Смена модели предметной области — ровно такое решение: у неё есть стоимость (переписанные модули, устаревшие диаграммы) и есть причина.

Когда абстракция действительно нужна

Чтобы не уехать в другую крайность — вот честные поводы завести слой:

  • Есть две реальных реализации. Не «может появиться», а есть сейчас: две модели, два провайдера, две базы.
  • Граница с чужой системой. Адаптер к внешнему API — тот самый Anti-corruption Layer: он не даёт чужой модели протечь в вашу.
  • Точка изменчивости, подтверждённая опытом. Вы уже дважды меняли это место за семестр — третий раз дешевле сделать через абстракцию.

Во всех трёх случаях слой оплачен фактом, а не предчувствием. Всё остальное — «на будущее», а будущее в студенческом проекте наступает редко: семестр заканчивается раньше.