Автор действительно имел в виду Unit Testing или есть что-то про
автоматизированное тестирование, которое мне не хватает?
Я прочитал это, чтобы иметь в виду модульное тестирование. Вы можете запускать модульные тесты вручную или в автоматическом режиме, если у вас есть непрерывный процесс интеграции / сборки.
Если автор намеревался написать автоматизированное тестирование, как бы
модифицируя этот класс, чтобы использовать вспомогательное средство для добавления зависимостей в процессе
автоматизированное тестирование?
Модификация поможет всем испытаниям, автоматизированным или нет.
В любом случае это применимо только в случае нескольких типов
платежных калькуляторов?
Это также может пригодиться, если ваш внедренный класс основан на интерфейсе, и вы хотите ввести прокси без необходимости изменения клиентского кода.
Если это так, то стоит ли применять DI с самого начала,
даже без знания требований, которые меняются в будущем?
Очевидно, что это требует некоторого усмотрения, который будет изучен через
опыт, поэтому я просто пытаюсь получить базовый уровень, на котором можно строить.
Это может помочь с самого начала, если у вас есть некоторое понимание того, как это работает и для чего это хорошо.
Преимущество есть, даже если требования не меняются. Ваши приложения будут лучше наслоены и будут основаны на интерфейсах для не значащих объектов (неизменяемые объекты, такие как Address и Phone, которые являются просто данными и не изменяются). Это обе передовые практики, независимо от того, используете ли вы механизм DI или нет.
ОБНОВЛЕНИЕ: Вот еще немного о преимуществах дизайна на основе интерфейса и неизменяемых объектов значения.
Объект значения является неизменным: после его создания вы не меняете его значение. Это означает, что это по сути потокобезопасно. Вы можете поделиться им в любом месте вашего приложения. Примерами могут служить примитивные оболочки Java (например, java.lang.Integer, класс Money и т. Д.)
Допустим, вам нужен человек для вашего приложения. Вы можете сделать его неизменным значением:
package model;
public class Person {
private final String first;
private final String last;
public Person(String first, String last) {
this.first = first;
this.last = last;
}
// getters, setters, equals, hashCode, and toString follow
}
Вы хотели бы сохранить Person, поэтому вам потребуется объект доступа к данным (DAO) для выполнения операций CRUD. Начните с интерфейса, потому что реализации могут зависеть от того, как вы решите сохранить объекты.
package persistence;
public interface PersonDao {
List<Person> find();
Person find(Long id);
Long save(Person p);
void update(Person p);
void delete(Person p);
}
Вы можете попросить механизм DI внедрить конкретную реализацию для этого интерфейса в любую службу, которая должна сохранять экземпляры Person.
Что если вы хотите транзакции? Легко. Вы можете использовать аспект, чтобы посоветовать ваши методы обслуживания. Одним из способов обработки транзакций является использование «throws advice» для открытия транзакции при входе в метод и либо фиксации после, если он успешен, либо откат ее, если она выдает исключение. Код клиента не должен знать, что есть аспект, обрабатывающий транзакции; все, что он знает, это интерфейс DAO.