Comments 18
Долгожданный ресерч от на тему микро-сервисов в андроиде) Огромное спасибо за статью) Однозначно плюсую, но у меня есть пару вопросов:
1. Как мульти-модульная архитектура ведет себя при тестировании? Нужно же, помимо обычных юнит-тестов в каждом модуле, писать интеграционные тесты на стыке 2,3,N модулей. Насколько сильно это может мешать или помогать?
2. CleanArch сегодня рекомендуют использовать практически в каждом проекте, вне зависимости от масштаба. Что скажешь по поводу много-модульности? Стоит ли ее юзать в ентерпрайзе или даже в небольшом аутсорсе от нее можно получить свои бенефиты?
3. А что насчет оверхеда? Размер .apk, путаница с повторным подключением библиотек? Насколько это может быть опасно и какие моменты надо продумать, прежде чем решить переводить свой проект на мульти-модульную архитектуру. Усложняет ли это разработку в команде или упрощает? Ведь придется наверное немного пересмотреть воркфлоу под такую архитектуру, имхо.
4. В данном контексте удачно вписывается Dagger. Что насчет других DI фреймворков? Toothpick, Koin, Kodein? Мне вот например очень сложным представляется тут возможность юзануть Koin…
Ну и под конец: Где-то на рэдите как-то прочитал постик, про то, что связь мульти-модульных архитектур можно реализовать по аналогии с бэкендом — посредством вызова удаленных процедур. Тогда каждый модуль является автономным, а его функции цепляются по RPC вызовам. Мне показалось это как-то оверхедно, но интересно. Хотелось бы услышать и ваше мнение)
1. Как мульти-модульная архитектура ведет себя при тестировании? Нужно же, помимо обычных юнит-тестов в каждом модуле, писать интеграционные тесты на стыке 2,3,N модулей. Насколько сильно это может мешать или помогать?
2. CleanArch сегодня рекомендуют использовать практически в каждом проекте, вне зависимости от масштаба. Что скажешь по поводу много-модульности? Стоит ли ее юзать в ентерпрайзе или даже в небольшом аутсорсе от нее можно получить свои бенефиты?
3. А что насчет оверхеда? Размер .apk, путаница с повторным подключением библиотек? Насколько это может быть опасно и какие моменты надо продумать, прежде чем решить переводить свой проект на мульти-модульную архитектуру. Усложняет ли это разработку в команде или упрощает? Ведь придется наверное немного пересмотреть воркфлоу под такую архитектуру, имхо.
4. В данном контексте удачно вписывается Dagger. Что насчет других DI фреймворков? Toothpick, Koin, Kodein? Мне вот например очень сложным представляется тут возможность юзануть Koin…
Ну и под конец: Где-то на рэдите как-то прочитал постик, про то, что связь мульти-модульных архитектур можно реализовать по аналогии с бэкендом — посредством вызова удаленных процедур. Тогда каждый модуль является автономным, а его функции цепляются по RPC вызовам. Мне показалось это как-то оверхедно, но интересно. Хотелось бы услышать и ваше мнение)
0
По вопросам:
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-вызовы и вот это все. Ну в целом Гугл уже продвигает тему динамических фич, так что мы постепенно становимся еще ближе к бекенду =)
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-вызовы и вот это все. Ну в целом Гугл уже продвигает тему динамических фич, так что мы постепенно становимся еще ближе к бекенду =)
0
Как адепт подобного подхода — одобряю! Спасибо, Евгений, что опубликовал столь информативный труд!
+1
Подход хороший, но я вижу в нем одну проблему, красивого решения которой я пока не придумал: шаринг моделей между фичами. Если какая-то модель нужна 2м фичам из 50-ти, то придется ее выносить в какую-то core сущность. И тут вилка или у нас будут плодиться такие core-сущности или распухать одна. Все становиться гораздо хуже, когда в проекте появляется room и тут уже вообще не очень понятно кто про кого должен знать учитывая специфику этой ORM. Если кто-то уже придумал как это все красиво разрулить, то буду рад вашим комментариям.
+1
Ну я бы зашел с такой стороны.
Одна фича может знать о другой, но не наоборот. То есть нужно исключать двусвязные зависимости, только однонаправленные. Соответственно, модели данных для шаринга логично расположить в апи фичи, о которой знают. То есть фича А знает о фиче Б, то тогда модели данных для шаринга располагаются в апи фичи Б.
Одна фича может знать о другой, но не наоборот. То есть нужно исключать двусвязные зависимости, только однонаправленные. Соответственно, модели данных для шаринга логично расположить в апи фичи, о которой знают. То есть фича А знает о фиче Б, то тогда модели данных для шаринга располагаются в апи фичи Б.
0
Я правильно понимаю, что при таком подходе сильно раздуваются интерфейсы модулей core-db-api и core-network-api (и их имплементации соответственно)? Я в поисках решения для реального переиспользования модулей в других проектах. И при таком подходе предвижу уйму методов в
HttpClientApi
и в DbClientApi
. Которые, к тому-же, не окажутся пригодными для переиспользования в условном другом проекте.0
Спасибо за статью, у меня есть сервис по обнаружению BlueTooth устройств в приложении, этим сервисом пользуются несколько разных экранов со своим workflow, я правильно понимаю стоит сделать features для:
1. сервиса BT устройств
2. сценарий #1
3. сценарий #2
?
1. сервиса BT устройств
2. сценарий #1
3. сценарий #2
?
0
Добавлю, что с Moxy, а точнее MoxyReflector, есть некоторые проблемы при дроблении на модули, из-за которых пришлось создать еще один дополнительный модуль :stub-moxy-java. Легкая щепотка магии, куда уж без нее.
А что за проблемы и что за магия? А то вот сегодня столкнулся с тем что презентер и вью в api описаны, реализация в impl, и в итоге дебаг версия нормально собирается, а релизная сборка падает.
0
Три года назад, в это самое время я ковырял outsource-ный проект на Cordove, паралельно пытаясь чего там накодить на котлине для внутренних нужд компании, и вот я здесь) Очень скоро наш проект нагонит все последние тренды - от Кордовы слава богу отказались как два года. Спасибо вам за статью. Интересно было бы узнать ваше внемние спустя три года? Чтобы сделали теперь иначе, лучше?
0
Ну я перехожу на другую реализацию: https://habr.com/ru/company/yandex/blog/419295/
0
Дык подход, описанный здесь, и то, что рассказывал Володя, мега коррелируют друг с другом =) Разве не так?
0
Sign up to leave a comment.
Многомодульность в Android с точки зрения архитектуры. От А до Я