Репосты из ветки Gradle .
То, что вы описываете, является довольно распространенным обсуждением систем с многоуровневой архитектурой, также известных как "строгие" или "свободные" многоуровневые, или "открытые""против" закрытых "слоев.См. Эту (надеюсь, бесплатную для вас) главу из Шаблоны архитектуры программного обеспечения для некоторых семиотик, которые вряд ли помогут вам с вашим выбором
С моей точки зрения, если модуль долженразделить слои, я бы смоделировал структуру проекта, чтобы показать это наиболее прямым и видимым способом.В этом случае это означает добавление library
в качестве зависимости реализации feature1
.Да, это делает диаграмму более уродливой, да, это заставляет вас при обновлении коснуться еще нескольких файлов, и в этом суть - у вашего дизайна есть недостаток, и он теперь виден.
Если нескольким модулям нужно разбить слойТаким же образом, я могу рассмотреть возможность добавления отдельного базового модуля, предоставляющего эту функциональность, с именем, например base-xyz
.Добавление нового модуля - большая вещь не из-за технической работы, а потому, что наш мозг может обрабатывать только очень много «вещей» за раз (чанкинг).Я полагаю, что то же самое относится и к «вариантам» Gradle, когда они станут доступны, но я не могу утверждать, что пока я не попробовал их на практике.
Если все клиенты модуля base
нуждаютсячтобы получить доступ к library
(т. е. поскольку вы используете классы или исключения из library
в своих публичных подписях), вы должны выставить library
как зависимость API от base
.Недостатком этого является то, что library
становится частью общедоступного API base
, и, вероятно, он больше, чем вы хотели бы, и не находится под вашим контролем.Публичный API - это то, за что вы несете ответственность, и вы хотите, чтобы оно было небольшим, документированным и обратно совместимым.
В этот момент вы можете подумать о модулях головоломки (хорошо), osgi (ошибаться ... дон't), или обертывание частей lib, которые вам нужно представить в ваших собственных классах (может быть?)
Обтекание только ради разрыва зависимостей - не всегда хорошая идея.С одной стороны, это увеличивает объем поддерживаемого вами кода и (надеюсь) документа.Если вы начинаете делать небольшие адаптации в слое base
, а library
- это хорошо известная библиотека, вы вносите (добавленную стоимость) несоответствия - нужно всегда быть настороже, сохраняются ли их предположения для lib.Наконец, часто тонкие обертки заканчивают утечкой дизайна библиотеки, поэтому, даже если они обертывают API - это все равно заставляет вас прикасаться к клиентскому коду при замене / обновлении lib, и в этот момент вам, возможно, было бы лучше использовать lib напрямую.
Итак, как вы видите, речь идет о компромиссах и удобстве использования.Процессору все равно, где лежат границы ваших модулей, и все разработчики разные - некоторые лучше справляются с большим количеством простых вещей, другие лучше справляются с небольшим количеством крайне абстрактных концепций.
Не зацикливайтесь налучший (как в «Что бы сделал дядя Боб») дизайн, когда подойдет любой хороший дизайн.Величина дополнительной сложности, которая оправдана ради введения порядка, является нечеткой величиной, и это то, что вы несете ответственность за принятие решения.Звоните лучше и не бойтесь изменить его завтра: -)