Стратегии - это вещи более высокого уровня, которые используются для изменения того, как они вычисляются.С помощью внедрения зависимостей вы можете изменить не только то, как все вычисляется, но и изменить то, что там есть.
Для меня это становится понятным при использовании модульных тестов.Для выполнения производственного кода у вас есть все данные скрыты (то есть частные или защищенные);тогда как в модульных тестах большая часть данных является общедоступной, поэтому я могу посмотреть на нее с помощью Asserts.
Пример стратегии:
public class Cosine {
private CalcStrategy strat;
// Constructor - strategy passed in as a type of DI
public Cosine(CalcStrategy s) {
strat = s;
}
}
public abstract class CalcStrategy {
public double goFigure(double angle);
}
public class RadianStrategy extends CalcStrategy {
public double goFigure(double angle) {
return (...);
}
}
public class DegreeStrategy extends CalcStrategy {
public double goFigure(double angle) {
return (...);
}
}
Обратите внимание, что нет открытыхданные, которые отличаются между стратегиями.Также нет никаких других методов.Обе стратегии используют одни и те же функции и сигнатуры.
Теперь для внедрения зависимости:
public class Cosine {
private Calc strat;
// Constructor - Dependency Injection.
public Cosine(Calc s) {
strat = s;
}
}
public class Calc {
private int numPasses = 0;
private double total = 0;
private double intermediate = 0;
public double goFigure(double angle) {
return(...);
}
public class CalcTestDouble extends Calc {
// NOTICE THE PUBLIC DATA.
public int numPasses = 0;
public double total = 0;
public double intermediate = 0;
public double goFigure(double angle) {
return (...);
}
}
Использование:
public CosineTest {
@Test
public void testGoFigure() {
// Setup
CalcTestDouble calc = new CalcTestDouble();
Cosine instance = new Cosine(calc);
// Exercise
double actualAnswer = instance.goFigure(0.0);
// Verify
double tolerance = ...;
double expectedAnswer = ...;
assertEquals("GoFigure didn't work!", expectedAnswer,
actualAnswer, tolerance);
int expectedNumPasses = ...;
assertEquals("GoFigure had wrong number passes!",
expectedNumPasses, calc.numPasses);
double expectedIntermediate = ...;
assertEquals("GoFigure had wrong intermediate values!",
expectedIntermediate, calc.intermediate, tolerance);
}
}
Обратите внимание на последние 2 проверки,Они использовали общедоступные данные в тестовом двойнике, которые были введены в тестируемый класс.Я не мог сделать это с производственным кодом из-за принципа сокрытия данных.Я не хотел вставлять специальный код тестирования в производственный код.Публичные данные должны были быть в другом классе.
Двойной тест вводили.Это отличается от стратегии, поскольку она влияет на данные , а не только на функции.