Pull to refresh

Comments 10

Вот к этой схеме есть вопрос: раз уже фича-1 использует фичу-2, а приложение - фичу1, то зачем нужна зависимость приложения от фичи-2, если она и так транзитивно попадёт в приложение?

Если говорить в контексте данного примера, то логика фичи-1 (feature-1-impl) знает только об интерфейсах фичи-2 (feature-2-api), но не о реализации (feature-2-impl). Соответственно реализацию всё ещё надо подключать к app. Так как на неё связей нет.

Если говорить в целом, то обычно фичи при написании подключают к app, а связи между фичами формируются позже в процессе написания дополнительной логики. Чтобы постоянно не отслеживать есть ли транзитивная связь на фичу, связь между app и фичей остаётся. Иначе пришлось бы переодически подключать/отключать фичу от app. Что не удобно. Gradle самостоятельно справляется с таким и делает это на отлично.

Я к тому, что двух слоёв можно сделать три: фича-1 зависит от фичи-2, а приложение зависит только от фичи 1, получая фичу 2 транзитивно. Это позволит увернуться от проблемы

логика фичи-1 (feature-1-impl) знает только об интерфейсах фичи-2 (feature-2-api)

ведь в этом случае зависимость от реализации фичи-2 сразу же даёт доступ к интерфейсам это самой реализации.

Вообще же зависимостям на одном уровне нежелательно зависеть друго от друга. Не будь у нас обращения изнутри фичи-1 к фиче-2 вопрос не стоял бы вовсе.

насколько понимаю, тут app тоже нуждается в фиче-2, просто об этом не написано. а делать фичу-2 транзитивной зависимостью через фичу-1 будет плохо, т.к. фича-2 станет недоступна в случае отключения фичи-1 от app.

Это уже вопрос к архитектуре. Такой кейс — хороший маркер: как так получается? Архитектура ведь не только про гибкость, но и про жесткость — принудительно пресекать разные вольности компоновки. Фича2, например, в принципе не должна быть доступна через слой.

P.S. Возможно тем, кто занимается данной темой известна статья, описывающая схему «ленивого» связывания модулей: https://habr.com/ru/post/536106/

В моем опыте построения и процесса разработки мультимодульных схем я пришел к необходимости создания автоматизированной системы управления зависимостями и сборки поверх Gradle, т.к. мультимодульность предполагает высокую градацию проекта на модули. Модули «мельчают» и, как следствие, их становится много. А в силу их высокой обособленности и независимости, они имеют свои жизненные циклы. Управлять этим хозяйством без автоматизации становится большой болью. Да и просто не реально. К тому же (и главное!) автоматизация зависимостей и сборки позволяет выстроить всю производственную цепочку разработки от бизнес-аналитики до тестирования и релиза.

Расскажите пожалуйста подробней про автоматизацию. Очень интересная тема. Интересует
1. На каких принципах строится проверка описанных вами проблем?
2. По каким критериям проходят проверки?
3. Проверка алармит подсвечивая потенциальные проблемы или кидает Exception об ошибке?
4. Чуть подробней как автоматизация зависимостей и сборки позволяет выстроить всю производственную цепочку разработки от бизнес-аналитики до тестирования и релиза?

Планирую в скором времени опубликовать описание. На данный момент идет идет процесс внедрения и дальнейшей разработки. Подробнее можно спросить у меня в телеграмме: https://t.me/Tepex — постараюсь по возможности ответить.

Спасибо за статьи! А есть хотя бы теоретическая возможность как то связать модули через написание gradle plugin или kapt? Что бы в процессе написания кода, feature-1 знал исключительно только о feature_2-api, но в процессе сборки происходила бы подмена. Для перекрестной связи в процессе написания кода использовать implementation "feaure_api-2" что бы иметь доступ к коду, но во время сборки заменять на runtimeOnly "feature_impl-2". В таком варианте api-2 оставался бы совсем чистым ничего не зная о реализациях и не выполнял бы функции Provider.

В теории подменить один модуль другим во время сборки мне кажется возможным. Например создать новый BuildType в котором будут зависимости на заглушки, использовать его в AndroidStudio. А вот в сборке debug/release уже подставлять реальные модули. В рамках эксперимента, ради интереса, это можно попробовать провернуть.

Но тогда мы от многомодульности возьмём только один аспект - разделение кода. Может сильно упасть скорость сборки, так как при изменении реализации, у нас вынуждены будут собраться все зависимые модули. А стоимость поддержки будет схожа с использованием api/feature.

Но это всё весьма теоритические рассуждения)

Sign up to leave a comment.