Pull to refresh

Comments 18

Долгожданный ресерч от на тему микро-сервисов в андроиде) Огромное спасибо за статью) Однозначно плюсую, но у меня есть пару вопросов:
1. Как мульти-модульная архитектура ведет себя при тестировании? Нужно же, помимо обычных юнит-тестов в каждом модуле, писать интеграционные тесты на стыке 2,3,N модулей. Насколько сильно это может мешать или помогать?
2. CleanArch сегодня рекомендуют использовать практически в каждом проекте, вне зависимости от масштаба. Что скажешь по поводу много-модульности? Стоит ли ее юзать в ентерпрайзе или даже в небольшом аутсорсе от нее можно получить свои бенефиты?
3. А что насчет оверхеда? Размер .apk, путаница с повторным подключением библиотек? Насколько это может быть опасно и какие моменты надо продумать, прежде чем решить переводить свой проект на мульти-модульную архитектуру. Усложняет ли это разработку в команде или упрощает? Ведь придется наверное немного пересмотреть воркфлоу под такую архитектуру, имхо.
4. В данном контексте удачно вписывается Dagger. Что насчет других DI фреймворков? Toothpick, Koin, Kodein? Мне вот например очень сложным представляется тут возможность юзануть Koin…

Ну и под конец: Где-то на рэдите как-то прочитал постик, про то, что связь мульти-модульных архитектур можно реализовать по аналогии с бэкендом — посредством вызова удаленных процедур. Тогда каждый модуль является автономным, а его функции цепляются по RPC вызовам. Мне показалось это как-то оверхедно, но интересно. Хотелось бы услышать и ваше мнение)
По вопросам:

1. По вопросам тестов пока придерживаюсь следующей картины мира.
Есть юнит-тесты. Это тестирование конкретного класса. Может быть тестирование совокупности классов (пример — тестирование интерактора, который внутри у себя дергает еще некоторые вспомогательные классы). Правда, в этом случае можно относить такие тесты к интеграционным, но все-таки тут тестируем конкретный юнит, который представлял из себя только один класс, но в процессе написания и дополнений распался на вспомогательные классы (SOLID и вот это все).
Все это на JUnit4/JUnit5/Spek.
Далее идут интеграционные и e2e тесты. Причем e2e тесты легко превращаются в интеграционные подменой нижнего слоя (например, Репозитория, или модуля, отвечающего за работу с сетью). Все это на Espresso + Kakao. Вот тут как раз можно спокойно тестировать конкретный фиче-модуль.
Тестирование заимодействия же модулей больше уходит в сторону e2e тестов, и тут с модулями у вас или нет — особой разницы нет.

2. По поводу повсеместного использования многомодульности. Как я уже говорил, многомодульность отлично решает вопрос корректного разбиения по фичам (разбиение по слоям делает CleanArch). Вы сразу же проектируете и пишите исходя из того, что каждая фича должна иметь конкретные контракты и их взаимодействие также должно подчиняться конкретным правилам. Прям архитектурный экстаз =)
Да, может быть определенный оверхед, но про Клин также говорили.
Может быть только в аутсорсе я бы упростил немного. Все в один модуль, а там разбиение по пакетам вместо разбиения по модулям.

3. Оверхед может возникнуть, например, с нативом. Каждый модуль будет формировать свои сошки, и это может нехило дать прирост в размере. Выход тут прост, весь натив у вас должен быть в одном модуле.
По поводу воркфлоу и командной работы. Мне кажется, что упростит работу и позволит вам, например, работать по Trunk-based development. Ведь обычный git-flow в команде уже 5+ разработчиков может вылиться в +100500 веток. А тут у вас вся разработка будет вестись в модулях и при необходимости вы сможете отключать не просто фиче-флаги, но весь ненужный код с ресурсами.

4. Другие DI фреймворки я не пробовал. Хватает Dagger 2 пока что =)

Про RPC-вызовы и вот это все. Ну в целом Гугл уже продвигает тему динамических фич, так что мы постепенно становимся еще ближе к бекенду =)
Как адепт подобного подхода — одобряю! Спасибо, Евгений, что опубликовал столь информативный труд!
Подход хороший, но я вижу в нем одну проблему, красивого решения которой я пока не придумал: шаринг моделей между фичами. Если какая-то модель нужна 2м фичам из 50-ти, то придется ее выносить в какую-то core сущность. И тут вилка или у нас будут плодиться такие core-сущности или распухать одна. Все становиться гораздо хуже, когда в проекте появляется room и тут уже вообще не очень понятно кто про кого должен знать учитывая специфику этой ORM. Если кто-то уже придумал как это все красиво разрулить, то буду рад вашим комментариям.
Ну я бы зашел с такой стороны.
Одна фича может знать о другой, но не наоборот. То есть нужно исключать двусвязные зависимости, только однонаправленные. Соответственно, модели данных для шаринга логично расположить в апи фичи, о которой знают. То есть фича А знает о фиче Б, то тогда модели данных для шаринга располагаются в апи фичи Б.
Я правильно понимаю, что при таком подходе сильно раздуваются интерфейсы модулей core-db-api и core-network-api (и их имплементации соответственно)? Я в поисках решения для реального переиспользования модулей в других проектах. И при таком подходе предвижу уйму методов в HttpClientApi и в DbClientApi. Которые, к тому-же, не окажутся пригодными для переиспользования в условном другом проекте.
Не совсем понял, почему раздуваются?
Данные модули просто предоставляют клиентов для работы с бд, сетью. А модели, конкретные запросы и вот это все — это дело фичи.

А что делать если скажем один и тот же репозиторий нужен для 2х разных фич? Выносить его как core модуль? Или feature?

Спасибо за статью, у меня есть сервис по обнаружению BlueTooth устройств в приложении, этим сервисом пользуются несколько разных экранов со своим workflow, я правильно понимаю стоит сделать features для:
1. сервиса BT устройств
2. сценарий #1
3. сценарий #2
?

Вопрос еще такой, а в каком месте например нужно инициализировать базу данных для приложения (например Room, там где все миграции, конвертертеры и нужен системный контекст для создания билдера базы данных)? Понятно что где-то в core-db-impl.

Добавлю, что с Moxy, а точнее MoxyReflector, есть некоторые проблемы при дроблении на модули, из-за которых пришлось создать еще один дополнительный модуль :stub-moxy-java. Легкая щепотка магии, куда уж без нее.

А что за проблемы и что за магия? А то вот сегодня столкнулся с тем что презентер и вью в api описаны, реализация в impl, и в итоге дебаг версия нормально собирается, а релизная сборка падает.

Три года назад, в это самое время я ковырял outsource-ный проект на Cordove, паралельно пытаясь чего там накодить на котлине для внутренних нужд компании, и вот я здесь) Очень скоро наш проект нагонит все последние тренды - от Кордовы слава богу отказались как два года. Спасибо вам за статью. Интересно было бы узнать ваше внемние спустя три года? Чтобы сделали теперь иначе, лучше?

Дык подход, описанный здесь, и то, что рассказывал Володя, мега коррелируют друг с другом =) Разве не так?

Расскажи, интересно же =)

Провел ревью своего старого проекта и схватил facePalm (нашел ошибку в формировании dagger-компонента), ты прав концептуально одинаковый подход.

Sign up to leave a comment.