Как убедиться, что данная зависимость включена в мое приложение с помощью Spring Framework? - PullRequest
7 голосов
/ 31 августа 2011

Это будет сложный вопрос для описания, но здесь идет.

Мы используем Delphi Spring Framework. (http://code.google.com/p/delphi-spring-framework/)

Допустим, у меня есть UnitA, который объявляет InterfaceA, который реализован ClassA.

Точно так же у меня есть UnitB, который объявляет InterfaceB, который реализован ClassB.

Оба зарегистрировали свой интерфейс и свой класс в контейнере Spring в соответствующих разделах инициализации.

InterfaceA зависит от InterfaceB, но поскольку мы используем Spring, UnitA не имеет UnitB в своем предложении uses. Другими словами, мы выполнили свою работу - мы разделили UnitA и UnitB, но мы все еще можем иметь InterfaceA зависимым от InterfaceB.

Однако, учитывая приведенный выше сценарий, мы должны убедиться, что и UnitA, и UnitB включены в проект, чтобы можно было разрешить зависимости.

Теперь представьте, что мы начинаем новый проект. Этот новый проект использует UnitA, но разработчик не понимает, что если нужно использовать UnitA, нужно также включить UnitB в проект. Не будет ошибки компилятора, поскольку зависимость разрешается во время выполнения, а не во время компиляции.

И в этом заключается вопрос: как правильно убедиться, что эта зависимость от UnitB известна до того, как приложение будет развернуто?

Мы можем предвидеть ситуацию в сложном приложении, когда, несмотря на тщательное тестирование, данный путь к коду не выполняется, возможно, в течение длительного времени, и эта отсутствующая зависимость не обнаруживается до развертывания.

Мы внедрили систему, в которой каждый вызов разрешения интерфейса сопровождается вызовом Requires, который проверяет и вызывает исключение при запуске, гарантируя, что мы увидим ошибку. Но нам интересно, есть ли «лучшая практика» или стандартный способ обнаружить это или иным образом решить эту проблему.

Добавлено: Это проблема в Java и других языках?

Ответы [ 2 ]

5 голосов
/ 31 августа 2011

Вам необходимо использовать решение для управления зависимостями, например Maven или Ivy . Как только вы это сделаете, вы сможете сказать, что UnitA зависит от UnitB, и как только кто-то добавит UnitA в качестве зависимости, инструмент (Maven или Ivy) будет вынужден загрузить зависимость и включить ее в ваш проект.

Сам Maven имеет Eclipse-плагин , который способен обнаруживать, даже если у вас уже есть другой проект в вашей текущей рабочей области.

2 голосов
/ 31 августа 2011

Я немного растерялся.Использование интерфейсов дает вам слабую связь, а не контейнер IoC.Вполне естественно, что UnitA будет использовать UnitB, если именно там объявлен InterfaceB.

Реализация интерфейсов - это отдельная история.Им потребуются ссылки на интерфейсы, которые они реализуют, и любые интерфейсы, которые они используют, но не должны быть ссылки на любые другие реализации.

Я не использовал Spring для Delphi, но я знаком с другими контейнерами IoC.Если он ведет себя аналогично, то вы регистрируете интерфейс вместе с его реализацией.Когда вы вызываете resolve, вы передаете либо имя интерфейса, либо некоторую другую информацию (тип info) об интерфейсе и ожидаете, что контейнер IoC вернет ссылку на запрошенный вами интерфейс.Какая реализация находится за этим интерфейсом, определяется тем, какие из них были зарегистрированы и какие правила существуют для разрешения запроса.

Если запрашиваемый вами интерфейс никогда не был зарегистрирован, вы получите исключение.Некоторые контейнеры IoC могут разрешать целые цепочки зависимостей одним вызовом.

Вы запрашиваете способ определить, будет ли зависимость разрешена во время выполнения, но зависимости не будут зарегистрированы до времени выполнения.Я не думаю, что это может быть гарантировано, независимо от того, какой инструмент вы используете.

UnitA должен включать UnitB в своем предложении использования.Реализации интерфейсов в UnitA и UnitB могут и, вероятно, должны быть расположены в блоках, отделенных от A и B, особенно если существует более одной реализации каждого интерфейса.

Разработчик, который использует UnitA в проекте, будетзатем будет вынужден включить UnitB в проект.Если они используют тестовую разработку в новом проекте, они довольно быстро обнаружат, что им нужно предоставить реализации (даже если они только фиктивные) для InterfaceA и InterfaceB для прохождения тестов.

Откровенно говоряЕсли пропущена критическая зависимость и проект развернут без нее, то тесты были недостаточно тщательными.Модульные тесты могут не уловить это, но это именно то, что обычно ловит набор интеграционных тестов.

Я бы рекомендовал что-то вроде Fit или Fitnesse для интеграционного тестирования (хотя я не уверен, насколько зрелым является проект Fit4Delphi ).Тесты могут быть написаны любым, кто может написать текстовый документ или отредактировать вики, и разработчик просто должен написать классы, которые позволяют тестам управлять производственным кодом.При правильной настройке вы можете запустить большинство интеграционных тестов в соответствии с актуальной версией проекта.

...