Инверсия управления Создание нового объекта

Я вхожу в Inversion of Control, в частности, использую Guice и RoboGuice для Android, и у меня есть вопрос.

У меня есть вызов метода, который возвращает ресурс (который по сути является строкой XML или JSON).

public Resource getResource(){
// Some implementation details that call a web service and throw the result in a string...
String resource = ........
}

Класс Resource на самом деле представляет собой обернутый класс String, поэтому я решил, что имеет смысл передать его в конструктор, поскольку он является неотъемлемой частью объекта Resource.

public class Resource{
   Resource(String theXMLorJSON){
   ...
   }
}

Пара вопросов:

  1. Как создать новый Resource в вызове getResource? Я бы подумал, что хочу использовать IoC, а не вызывать new в методе.
  2. Если другой класс принимает Resource в конструкторе, как я могу использовать контейнер Guice для его создания, когда мне нужен динамический String во время построения? Я только что задал похожий вопрос и считаю, что может быть особый способ справиться с этим, используя Guice.

Большое спасибо!


person skaz    schedule 19.11.2011    source источник


Ответы (1)


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

Однако ваш класс Resource звучит как простой объект-значение, который вы можете легко создать вручную при любом тестировании. Он также не зависит от каких-либо служб... он просто содержит String. Поэтому нет причин пытаться создать контейнер.

С другой стороны, класс, содержащий метод getResource(), вы определенно хотите, чтобы контейнер создавался, потому что вы хотели бы иметь возможность использовать что-то, что зависит от этого класса, при тестировании без фактического вызова веб-службы.

Обратите внимание: если у вас есть класс с конструктором, который принимает как зависимости, которые вы хотите внедрить контейнером, так и параметры, которые известны только во время выполнения, вам необходимо создать какую-то промежуточную фабрику с методом, который принимает только параметры времени выполнения. С помощью Guice вы можете автоматически создать такую ​​фабрику из интерфейса с помощью вспомогательной вставки (не уверен, что это работает с RoboGuice, но такую ​​фабричную реализацию также легко создать вручную).

person ColinD    schedule 19.11.2011
comment
Большое спасибо за ответ. Я также в Арлингтоне, штат Вирджиния, кстати. - person skaz; 20.11.2011
comment
Еще пара вопросов, если не возражаете. 1) Почему пример в разделе «Фабрики вручную» на странице, на которую вы ссылаетесь, принимает Provider вместо CreditService? Нельзя ли просто ввести CreditService? 2) Если у меня есть другой класс, ResourceUser, который принимает Resource в конструкторе, а конструктор Resource принимает String, как мне настроить ResourceUser с помощью Guice? Извините, если это наивно... - person skaz; 20.11.2011