Рассмотрим случай, когда мы могли бы захотеть использовать службу, такую как
class MyService {
public double calculateSomethingVeryComplex();
}
. Эти функционально выглядящие классы (которые содержат только один метод) имеют тенденцию отображать только одинпубличный метод, хотя мы знаем (или представим хотя бы), что они составлены из множества внутренних методов меньшего размера:
class MyService {
public double calculateSomethingVeryComplex()
private double getA();
private double getB();
private double getC();
...
}
и, хотя метод main обычно может передавать свои объекты в getA()
,getB()
, ...
, через аргументы метода мы обычно склонны определять их как атрибуты (поля) класса, чтобы выполнить работу:
class MyService {
private double val1;
private double val2;
private double val3;
public double calculateSomethingVeryComplex()
private double getA();
private double getB();
private double getC();
...
}
Если не использовать внедрение зависимостей, каждый раз, когда мынам нужно вычислить что-то очень сложное, мы просто создаем новый MyService
, вызываем его единственный метод, и все готово.
При использовании внедрения зависимостей у нас возникает очевидная проблема желания создать экземпляр MyService
в корне композиции, что почти нормально, хотя с этими частными полями могут быть проблемы (например, в многопоточном сценарии).
Я вижу 3 основныхварианты здесь:
- Создайте
MyServiceFactory
, который у меня есть, как зависимость от любого класса, который хочет использовать MyService
.Мне не нравится этот подход, так как он может в некоторых приложениях стремительно увеличить количество классов и кажущуюся сложность системы. - Инкапсулирует текущий класс
MyService
в другой, который несет ответственность за:создание экземпляра MyService
, его запуск, а затем возврат вычисленного значения из него.Это кажется хорошим, так как открытый API класса такой же, как и исходный, и мы без проблем используем внедрение зависимостей. - Пусть все будет так, как есть.Если мы попытаемся запустить 2 параллельных вычисления, у нас могут возникнуть проблемы с параллелизмом.Если мы попытаемся запустить один и тот же метод дважды один за другим, у нас могут возникнуть проблемы и с повторным использованием поля.
Второй пункт кажется очевидным победителем.Есть ли другая лучшая альтернатива пункту 2 или какой-либо из показанных точек?