Экстремальное программирование. Разработка через тестирование | страница 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. Ретроспектива денежного примера

Давайте еще раз окинем взглядом пример реализации мультивалютных вычислений и попробуем оценить использованный нами подход и полученные результаты. Вот несколько тезисов, которых хотелось бы коснуться: