Экстремальное программирование. Разработка через тестирование | страница 46
Money result = bank.reduce(fiveBucks.plus(tenFrancs), "USD");
assertEquals(Money.dollar(10), result);
}
Компилятор вежливо сообщает, что plus() не является методом интерфейса Expression. Добавим этот метод в интерфейс:
Expression
Expression plus(Expression addend);
Теперь мы должны добавить этот метод в классы Money и Sum. Money? Да, этот метод должен быть открытым (public) в классе Money:
Money
public Expression plus(Expression addend) {
return new Sum(this, addend);
}
Что касается класса Sum, просто добавим заглушку и отметим необходимость реализации этого метода в списке задач:
Sum
public Expression plus(Expression addend) {
return null;
}
$5 + 1 °CHF = $10, если курсобмена 2:1
$5 + $5 = $10
Операция $5 + $5 возвращает объект Money
Bank.reduce(Money)
Приведение объекта Money с одновременной конверсией валют
Reduce(Bank,String)
Sum.plus
Expression.times
Теперь программа компилируется и все тесты выполняются успешно.
Мы готовы завершить обобщение класса Money до Expression, но прежде, как всегда, подведем краткий итог. В этой главе мы
• за один шаг написали необходимый тест и затем модифицировали его, чтобы добиться успешного его выполнения;
• выполнили обобщение (использовали более абстрактное объявление);
• воспользовались подсказками компилятора, чтобы внести изменения (Expression fiveBucks), которые привели к необходимости дополнительных изменений (добавление метода plus() в интерфейс Expression и т. п.).
16. Абстракция, наконец-то!
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 + $5 = $10
Операция $5 + $5 возвращает объект Money
Bank.reduce(Money)
Приведение объекта Money с одновременной конверсией валют
Reduce(Bank,String)
Sum.plus
Expression.times
Чтобы завершить добавление метода Expression.plus, мы должны реализовать метод Sum.plus(). Затем нам останется добавить метод Expression.times(), и мы сможем считать пример завершенным. Вот тест для метода Sum.plus():
public void testSumPlusMoney() {
Expression fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Expression sum = new Sum(fiveBucks, tenFrancs). plus(fiveBucks);
Money result = bank.reduce(sum, "USD");
assertEquals(Money.dollar(15), result);
}
Мы могли бы создать объект Sum путем сложения fiveBucks и tenFrancs, однако приведенный код, который явно создает объект Sum, выглядит более понятным. Ведь мы пишем эти тесты не только ради удовольствия от программирования, но также для того, чтобы будущие поколения программистов могли оценить нашу гениальность. Однако они не смогут сделать этого, если код будет непонятным. Поэтому, разрабатывая любой код, думайте о тех, кто будет его читать.