Основная причина заключается в том, что OSGi является спецификацией для многократно используемого компонента системы. Если вы попытаетесь сделать это с помощью транзитивных зависимостей, вы обнаружите, что вы столкнулись с проблемами во время сборки:
- версии версий - компонент A использует версию 1 X, компонент B использует версию 2 X. Эти конфликты часто сужаются в переходных системах, таких как Maven, но бомбы замедленного действия скрываются в go.
- зависимости от окружения - некоторые компоненты зависят от Windows, другие от Linux. Очень трудно примирить эти различия.
- совместимость версий - часто компоненты могут работать вместе, но их переходные зависимости делают невозможным.
Для решения этой проблемы OSGi изобрела сервисная модель . Модель сервиса позволяет компоненту зависеть от API . Как только вы зависите от API, у вас больше не будет транзитивных зависимостей, так как транзитивные зависимости почти все о зависимостях реализации . Конечно, существует зависимость от API, но она становится нечеткой, поскольку от этого зависят как пользователь API, так и поставщик API. Это в корне меняет модель зависимости в лучшую сторону, но мало кто это делает.
Т.е. в сервисной модели доллар останавливается на сервисном API. Вы компилируете по API и можете написать множество тестов по API. Однако ваш компонент никогда не должен зависеть от конкретной реализации c. Первый раз, когда ваш компонент увидит, что реализация должна быть во время выполнения.
Конечно, это лишается некоторого удобства на ранних стадиях разработки. В тех случаях, когда в транзитивной модели, такой как Maven, все должно компилироваться «из коробки», в bnd вам нужно заранее подумать о ваших и ваших компонентных зависимостях. Это неудобно и раздражает пользователей Maven, но необходимо сделать компоненты многоразовыми в самых разных средах. Maven имеет тенденцию блокировать среду выполнения в часто несовместимых конфигурациях, в OSGi вы не хотите, чтобы среда выполнения имела какие-либо ненужные ограничения, чтобы максимизировать возможность повторного использования ваших компонентов.
Часто это накладывает ограничение на разработчиков, никаких зависимостей реализации. слишком много для разработчиков, привыкших к краткосрочному удобству переходных зависимостей. Тем не менее, разработчики, которые используют эту модель, быстро понимают, что она открывает множество возможностей на более поздних этапах цикла разработки и значительно сокращает объем обслуживания. Даже я иногда испытываю желание пропустить этот уровень косвенности, но каким-то образом, даже при небольшой сложности, я возвращаюсь, потому что модель имеет так много преимуществ на макроуровне.
Я участвовал во многих сложных системах, и практически во всех случаях большая сложность исчезает, когда вы убиваете сирены с транзитивной зависимостью.