Можно ли обойтись без слоя сущностей в чистой архитектуре
Что проверяют
Понимаете ли вы, что такое Entities в чистой архитектуре, и не путаете ли их с @Entity из Room или с DTO из Retrofit. Следом обычно просят показать, как данные идут из сети до экрана и где происходит маппинг.
Как отвечать
Сначала определение. У Роберта Мартина Entities это внутренний круг: бизнес-объекты и правила, которые верны независимо от конкретного приложения. Они не знают про Android, базу и сеть. В Android-проектах эту роль играют доменные модели, обычно Kotlin-классы в модуле :domain без Android-зависимостей.
Дальше честный ответ: обойтись можно, и это не ересь. В руководстве Google по архитектуре приложений обязательны UI-слой и слой данных, а доменный слой с use case помечен как необязательный. Но что именно вы выкидываете, стоит понимать:
- без отдельных моделей: UI работает прямо с DTO. Бэкенд переименовал поле, и правки расходятся по экранам, а аннотации
@SerialNameили@Jsonпротекают в презентационный слой; - с моделями: появляются мапперы вроде
NetworkUser.toDomain()иUserEntity.toDomain(). Это лишний код, зато ответ API и схема Room меняются независимо от экранов; - компромисс для маленького приложения: две модели, данные и UI, маппинг в репозитории, без отдельного модуля домена.
Критерий выбора: если в приложении есть правила, которые стоит тестировать отдельно (расчёт скидки, валидация, переходы статусов заказа), им нужен свой слой с чистыми моделями и быстрыми юнит-тестами без Robolectric. Если приложение показывает список из API и почти ничего не считает, отдельный слой сущностей даст только мапперы.
Где спотыкаются
Путают Entities из чистой архитектуры с таблицами Room. Кандидат говорит «сущности у нас есть, вот @Entity», а это модель хранения, то есть внешний слой.
Предлагают заменить слой сущностей через ViewModel. Это презентационный слой, и бизнес-правила в нём быстро превращаются в копипаст между экранами.
Строят анемичные доменные модели: те же поля, что в DTO, никакого поведения, плюс три маппера. Такой слой только множит код и ничего не защищает.