Экстремальное программирование. Разработка через тестирование | страница 48
Sum
public Expression times(int multiplier) {
return new Sum(augend.times(multiplier), addend.times(multiplier));
}
Money
public Expression times(int multiplier) {
return new Money(amount * multiplier, currency);
}
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 + $5 = $10
Операция $5 + $5 возвращает объект Money
Bank.reduce(Money)
Приведение объекта Money с одновременной конверсией валют
Reduce(Bank,String)
Sum.plus
Expression.times
Все заработало.
Осталось провести эксперимент для случая, когда в результате выполнения операции $5 + $5 получается объект Money. Вот соответствующий тест:
public void testPlusSameCurrencyReturnsMoney() {
Expression sum = Money.dollar(1). plus(Money.dollar(1));
assertTrue(sum instanceof Money);
}
Тест выглядит несколько неопрятно, так как тестирует внутреннюю реализацию, а не внешнее поведение объектов. Однако он принуждает нас внести в программу изменения, которые нам необходимы, и, в конце концов, это всего лишь эксперимент. Вот код, который мы должны модифицировать, чтобы заставить тест работать:
Money
public Expression plus(Expression addend) {
return new Sum(this, addend);
}
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 + $5 = $10
Операция $5 + $5 возвращает объект Money
Bank.reduce(Money)
Приведение объекта Money с одновременной конверсией валют
Reduce(Bank,String)
Sum.plus
Expression.times
Не существует очевидного и ясного способа проверить валюту аргумента, если этот аргумент является объектом класса Money (по крайней мере, я не могу найти такого способа, однако вы можете над этим подумать). Эксперимент окончился неудачей, мы удаляем тест (который нам все равно не нравился).
Подводим итог. Мы
• написали тест так, чтобы его смысл легко был понят другими программистами, которые в будущем будут читать разработанный нами код;
• наметили эксперимент, призванный сравнить эффективность TDD по отношению к обычному стилю программирования, используемому вами на текущий момент;
• снова столкнулись с необходимостью изменения множества объявлений в разрабатываемом коде и снова воспользовались услугами компилятора, чтобы исправить все неточности;
• попробовали провести быстрый эксперимент, однако отказались от идеи, так как она не сработала, и уничтожили соответствующий тест.
17. Ретроспектива денежного примера
Давайте еще раз окинем взглядом пример реализации мультивалютных вычислений и попробуем оценить использованный нами подход и полученные результаты. Вот несколько тезисов, которых хотелось бы коснуться: