Инверсия контроля создания нового объекта - PullRequest
1 голос
/ 20 ноября 2011

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

У меня есть вызов метода, который возвращает Resource (который по сути является строкой 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.

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

1 Ответ

2 голосов
/ 20 ноября 2011

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

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

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

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

...