Вкладные зависимости в методах или в конструкторе?
Инъекционная инъекция кажется хорошей. В общем случае, следует ли вводить зависимости в соответствии с методами, которые их требуют, или они должны быть введены в конструктор класса?
См. примеры ниже, чтобы продемонстрировать два способа введения той же зависимости.
//Inject the dependency into the methods that require ImportantClass
Class Something {
public Something()
{
//empty
}
public void A()
{
//do something without x
}
public void B(ImportantClass x)
{
//do something with x
}
public void C(ImportantClass x)
{
//do something with x
}
}
//Inject the dependency into the constructor once
Class Something {
private ImportantClass _x
public Something(ImportantClass x)
{
this._x = x;
}
public void A()
{
//do something without x
}
public void B()
{
//do something with this._x
}
public void C()
{
//do something with this._x
}
}
Ответы
Ответ 1
Основным преимуществом инъекции конструктора является то, что он позволяет отмечать ваши поля окончательными. Например:
class Foo {
private final Bar _bar;
Foo(Bar bar) {
_bar=bar;
}
}
На следующей странице есть отличный список про и con: Лучшие практики Guice:
Ввод метода
- + Не вводить поле
- + Единственное, что работает для некоторых странных случаев края
Ввод конструктора
- + Поля могут быть окончательными!
- + Инъекция не может быть пропущена.
- + Легко видеть зависимости с первого взгляда.
- + Это то, о чем идея построения - это
- - Нет дополнительных инъекций
- - Бесполезно, если библиотека DI не может выполнять сам экземпляр
- - Подклассы должны "знать о" инъекциях, необходимых их суперклассам
- - Менее удобно для тестов, которые только "заботятся" о одном из параметров
Ответ 2
Не вставляя зависимость для каждого метода, вы вынуждаете каждого вызывающего пользователя знать или получать зависимость.
Кроме того, с точки зрения инструментария доступно много доступных фреймворков (по крайней мере, в .NET), которые позволяют или делают инъекцию конструктора намного проще. Это не должно влиять на решение, но делает его гораздо более привлекательным.
Удачи.
Ответ 3
Если вы вводите во время методов, чем вы не различаете поведенческую абстракцию от конкретных зависимостей. Это большой нет нет:). Вы хотите зависеть от абстракций, чтобы не сочетаться с зависимостями зависимостей ваших классов.,
Поскольку ваш конструктор не будет присутствовать в каком-либо интерфейсе, который поддерживает ваш конкретный класс, чем вы не связываетесь с этой зависимостью. Но вызов метода будет иметь эту проблему.
Вот хорошая статья об этом типике:
http://chrisdonnan.com/blog/2007/05/20/conquest-through-extreme-composition-glue-part-2/
Ответ 4
Сумасшедший Боб Ли говорит, что по возможности использует инъекцию конструктора. Используйте только инъекцию метода, когда у вас нет контроля над экземпляром (например, в сервлете).
Ответ 5
Другим способом является пользователь, устанавливающий для зависимостей. Иногда это сочетается с инъекцией конструктора. Это может быть полезно, если вы хотите изменить версию, которую вы используете позже, без необходимости повторного создания экземпляра.
public interface IFoo
{
void Do();
}
public class IFoo DefaultFoo : IFoo
{
public void Do()
{
}
}
public class UsesFoo
{
private IFoo foo;
public IFoo Foo
{
set { this.foo = value; }
}
public UsesFoo()
{
this.Foo = new DefaultFoo();
}
public UsesFoo( IFoo foo )
{
this.Foo = foo;
}
public void DoFoo()
{
this.Foo.Do();
}
}
Ответ 6
Я имею тенденцию использовать второй метод, но тогда это потому, что я стараюсь сделать мои pojos beans, что означает, что конструктор аргументов 0 полезен.