2016-05-04 2 views
1

У меня есть проект Scala A, который имеет интерфейс (абстрактный класс) I, его реализации и ссылку на проект B (B.jar). A упакован с publish-local для компиляции в файл jar и хранится в каталоге .ivy. Проект B, в свою очередь, использует интерфейс I в проекте B; он скомпилирован в банку и в каталог .ivy.Циркулярная зависимость в Scala

Сюда приходят некоторые конструктивные вопросы в Scala:

  • Является ли это циклическая зависимость при А относится к В, если В относится к А?
  • Если первый вопрос является проблемой, я думаю, что упрощенное решение состоит в том, чтобы извлечь интерфейс I из A, сделать его еще одним проектом, на который будут ссылаться как A, так и B. Не является ли этот избыточный проект проектом, который имеет только один интерфейс? Или это нормально, так как B ссылается только на один файл класса в A. Какая практика в Scala?
+1

нет его не круговая зависимость, ну это на бумаге. но не на компиляторе. –

ответ

0

Трудно дать совет «лучшей практики» без особых подробностей. Если «проект B» тесно связан с проектом A, они, вероятно, должны быть в одном проекте, но в разных подпроектах/подмодулях. Использование интерфейса B также может быть его собственным подпроектом для удаления круга.

sbt и maven поддерживают это, here's the sbt docs.

2

Бывают случаи, когда так называемая циклическая зависимость может уменьшить количество строк кода и поэтому не может быть обескуражена как «плохая практика» де-факто. Все зависит от контекста проекта. Вам нужны ответы на такие вопросы, как:

  1. Нужны ли проекты в разных библиотеках?
  2. Если это так, мы можем рассмотреть возможность использования каркаса DI. например, Spring, Guice и т. д.

Тогда, поскольку это scala, вам действительно не нужен framework за использование, чтобы реализовать это.

Рассмотрим следующий пример,

class IdentityCard(val id: String, val manufacturerCompany: String, person: => Person) 
    class Person(val firstName: String, val lastName: String, icard: => IdentityCard) 

    lazy val iCard = new IdentityCard("123","XYZ",person) 
    lazy val person:Person = new Person("som","bhattacharyya",iCard) 

Эти два класса могут быть в отдельных банках и компилироваться и работать вместе с меньшим количеством кода. Обратите внимание, что мы используем call-by-name для передаваемых зависимостей. Также мы выполняем ленивую инициализацию переменных, чтобы они не оценивались до тех пор, пока они не будут доступны. Это позволяет нам forward-reference т.е. сначала используя переменную и определяя ее позже.

Смежные вопросы