2009-02-10 7 views
16

Зависит ли инъекция означает, что вам никогда не понадобится «новое» ключевое слово? Или разумно ли прямо создавать простые листовые классы, такие как коллекции?Есть ли когда-либо случай для «нового» при использовании инъекции зависимостей?

В приведенном ниже примере я впрыснуть компаратор, запрос и дао, но SortedSet непосредственно инстанцирован:

public Iterable<Employee> getRecentHires() 
{ 
    SortedSet<Employee> entries = new TreeSet<Employee>(comparator); 
    entries.addAll(employeeDao.findAll(query)); 
    return entries; 
} 

ответ

9

Просто потому, что Dependency Injection является полезным картина не означает, что мы используем его для всего. Даже при использовании DI часто возникает необходимость в . Не удалять новые.

0

Да, конечно.

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

Однако есть достаточно ситуаций, когда вы точно знаете, что хотите создать, поэтому нет необходимости в DI.

Это похоже на вызов функций в объектно-ориентированных языках: только потому, что вы можете использовать динамическое связывание, не означает, что вы не можете использовать старую старую диспетчерскую службу (например, когда вы разбиваете свой метод на несколько частных операций).

4

Нет ничего плохого в использовании , как показано в вашем фрагменте кода.

Рассмотрите случай добавления фрагментов String. Почему вы хотите спросить инжектора для StringBuilder?

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

6

Как правило, я решаю, следует ли использовать инъекцию зависимостей, нужно ли мне издеваться или заглушить сотрудничающий класс при написании модульного теста для тестируемого класса. Например, в вашем примере вы (правильно) вводите DAO, потому что, если вы пишете модульный тест для своего класса, вы, вероятно, не хотите, чтобы какие-либо данные фактически были записаны в базу данных. Или, возможно, сотрудничающий класс записывает файлы в файловую систему или зависит от внешнего ресурса. Или поведение непредсказуемо или сложно учесть в единичном тесте. В этих случаях лучше всего вводить эти зависимости.

Для таких классов, как TreeSet, я обычно не вводил их, потому что обычно нет необходимости издеваться над простыми классами, подобными этим.

Последнее замечание: когда поле не может быть введено по какой-либо причине, но я все же хотел бы издеваться над ним в тесте, я нашел класс Junit-addons PrivateAccessor полезным для переключения частного поля класса в макет объект, созданный EasyMock (или jMock или любой другой смешной каркас, который вы предпочитаете).

+0

Весна также имеет класс 'ReflectionTestUtils' для операций с частными членами. –

0

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

Так что, когда DI является излишним, я использую «новое» и просто позволяю ему рулон.

Ex: для меня проводка модели с видом на слой контроллера. Это всегда делается с помощью DI. Любые алгоритмы, которые используют мои приложения, DI, а также любой подключаемый отражающий код, DI. Уровень базы данных .. DI, но практически любой другой объект, используемый в моей системе, обрабатывается с помощью общего «нового».

надеюсь, что это поможет.

0

Это правда, что в сегодняшней среде, основанной на каркасе, вы все меньше создаете объекты. Например, сервлеты создаются с помощью контейнера сервлетов, бобов в Spring, созданных с помощью пружины и т. Д.

Тем не менее, при использовании слоя сохранения вы создадите экземпляр ваших сохраняемых объектов до того, как они будут сохранены. При использовании Hibernate, например, вы будете вызывать новое на своем сохраненном объекте до вызова сохранения на свой HibernateTemplate.