Наконец-то подоспел ответ =)
1. Бизнес-логика и модели данных. Знаете, я соглашусь с тем, что Бизнес-логика не должна ничего знать о моделях данных Даты-уровня и UI-уровня. Эти знания ей ни к чему. Плюс да, во всех источниках бизнес-логика представляется максимально изолированной от всех слоев. А тут я ее наоборот загружаю лишними данными и серьезно завязываю на конкретные модели. Поэтому Репозиторий должен предоставлять Интерактору уже готовые бизнес-модели, а Интерактор выдает ui уже обновленные, но тоже свои бизнес-модели, UI при необходимости мапит их.
2. Место Репозитория. Я бы не стал относить Репозиторий чисто к бизнес-логике. Но это это и не Дата-уровень. По мне, Репозиторий - это надстройка над Датой, с которой непосредственно взаимодействует бизнес-логика. Именно Репозиторий решает, откуда брать данные и как.
3. Обязанности Репозитория + вопросы кеширования. С осознанием того, что Бизнес-логика ничего не знает о моделях Даты, и что она получает уже готовые бизнес-модели от Репозитория, роль Репозитория несколько меняется. Теперь это не просто проводник запросов в сеть или БД. Теперь Репозиторий отвечает за маппинг данных, выбор источников данных, а также за кеширование. Интерактору выдается просто готовые модели. Раньше у меня Интерактор знал о моделях Даты и мог сам принимать решения, как кешировать. Но это не верно и не очень красиво.
Есть возражения, что если осуществлять еще и кеширование, то как-то много всего будет в Репозитории. Ну тут остается только посоветовать - делегируйте во вспомогательные классы. У Фернандо показан хороший пример делегирования через Фабрику и DataStore (в статье
http://hannesdorfmann.com/android/evolution-of-the-repository-pattern, раздел Evolution of the Repository Pattern term). Там фабрика решает, какой DataStore задействовать для конкретного id.
Если для принятия решения о кешировании нужна информация с другого Репозитория, то пускай Интерактор передаст через аргумент метода нужную инфу в Репозиторий. Вообщем тут Интерактор отвечает за взаимодействием и необходимый обмен информацией между Репозиториями. Например у одного репозитория запросил, какой режим сейчас (пользовательский или демо), а в другой репозиторий передал эти данные для получения корректного списка операций.
modeRepository.getMode()
.flatMap(mode -> operationsRepository.getOperations(mode))
4. Исходя из вышесказанного Репозиторий должен тестироваться.
5. Если вам нужно сделать приложение быстро, можно, конечно, не заморачиваться с маппингом, а передавать модель, полученную с запроса. Но если приложение чуть более серьезное и долгое, то лучше маппить. Так как по своему опыту, по Дате-уровне или по логике получения данных всегда что-то может поменяться. Бизнес-логика про это вообще не должна знать.
6. Про проектирование. У меня в докладе показано проектирование снизу вверх. Но почитав источники Александра соглашусь, что проектирование сверху-вниз намного более привлекательней, да и позволяет быстро получить результат.
Один бы я не дошел до этого. Вот что значит коллективный разум! Еще раз спасибо Александру за отличный вопрос и очень развернутое свое мнение. Заставил меня несколько переосмыслить некоторые вещи.