Правильное использование «внедрения в конструктор». Как обрабатывать зависимости при вызове классов?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Правильное использование «внедрения в конструктор». Как обрабатывать зависимости при вызове классов?

Сообщение Anonymous »

Интересно, не ошибаюсь ли я в своих мыслях при использовании «Инъекции в конструктор»:
Дано два правила, которые имеют совершенно разные задачи и зависимости использовать.
Чтобы сделать их пригодными для модульного тестирования, я внедряю эти зависимости через конструктор.

Код: Выделить всё

class RuleA implements MyInterface {

private DependencyA_1 dependencyA1;
private DependencyA_2 dependencyA2;

public RuleA(DependencyA_1 dependencyA1, DependencyA_2 dependencyA2) {
this.dependencyA1 = dependencyA1;
this.dependencyA2 = dependencyA2;
}

public Result execute() {
....
}

Код: Выделить всё

class RuleB implements MyInterface {

private DependencyB_1 dependencyB1;
private DependencyB_2 dependencyB2;

public RuleB(DependencyB_1 dependencyB1, DependencyB_2 dependencyB2) {
this.dependencyB1 = dependencyB1;
this.dependencyB2 = dependencyB2;
}

public Result execute() {
....
}
Только при наличии строки (например, из результата БД) для создания правильного правила я создаю фабрику для создания экземпляра.
Но если Я делаю это: моя фабрика должна знать каждую зависимость всех моих правил, что (по моему мнению) является большой проблемой связи, и если я хочу провести модульное тестирование своей фабрики, мне нужно высмеять все эти зависимости , о чем моя фабрика не должна знать.
Поэтому для производственного кода я бы добавил конструкторы без аргументов в RuleA и RuleB, в которых создаются экземпляры "реальных" объектов, например:

Код: Выделить всё

 public RuleA(DependencyA_1 dependencyA1, DependencyA_2 dependencyA2) {
this.dependencyA1 = dependencyA1;
this.dependencyA2 = dependencyA2;
}

public RuleA() {
this(new MyProductiveDependencyA1(), new MyProductiveDependencyA2());
}

....

Код: Выделить всё

class Factory {

public MyInterface createClass(String type) {
if ("A".equals(type)) {
return new RuleA();
}

if ("B".equals(type)) {
return new RuleB();
}

}
Но теперь моя фабрика или любой другой класс, который ее использует, не подлежит модульному тестированию из-за использования производственных конструкторов RuleA и RuleB, которые могут потребовать запуска БД или какие-либо внешние модули.
Поэтому мои вопросы:
Хорош ли шаблон использовать один конструктор для модульного тестирования и еще один для «нормального/производственного» использования (если, конечно, в нем нет логики)?
Если я использую конструктор модульного тестирования при вызове классов, им нужно знать все зависимости вызываемого класса, а если подумать о более глубоких иерархиях, это может стать очень запутанным. Если я использую конструктор без аргументов, вызывающий класс не подлежит модульному тестированию. Что мне делать? Нужно ли мне признать, что эти классы можно тестировать только в интеграционных тестах или это запах плохого дизайна программного обеспечения?
Я знаю, что есть пара фреймворков внедрения зависимостей, использующих аннотации, чтобы я мог имитировать необходимые зависимости, не передавая их через конструкторы, но я хотел бы избегать их, если это возможно.

Подробнее здесь: https://stackoverflow.com/questions/791 ... es-in-call
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»