Экстремальное программирование. Разработка через тестирование | страница 38



Money reduced = bank.reduce(sum, "USD");

assertEquals(Money.dollar(10), reduced);

}


Наконец, операция, в которой мы абсолютно уверены, – создание пяти долларов:


public void testSimpleAddition() {

Money five = Money.dollar(5);

Expression sum = five.plus(five);

Bank bank = new Bank();

Money reduced = bank.reduce(sum, "USD");

assertEquals(Money.dollar(10), reduced);

}


Что надо сделать, чтобы данный код откомпилировался? Для начала создадим интерфейс Expression (мы могли бы создать класс, однако интерфейс обладает существенно меньшим весом):


Expression

interface Expression


Метод Money.plus() должен возвращать значение типа Expression:


Money

Expression plus(Money addend) {

return new Money(amount + addend.amount, currency):

}


Это означает, что класс Money должен реализовать интерфейс Expression (это очень просто, так как в этом интерфейсе пока что нет ни одной операции):


Money

class Money implements Expression


Кроме того, нам потребуется пустой класс Bank:


Bank

class Bank


Добавим в этот класс заглушку для метода reduce():


Bank

Money reduce(Expression source, String to) {

return null;

}


Теперь код компилируется и выдает нам красную полоску. Ура! У нас прогресс! Теперь можем легко подделать реализацию:


Bank

Money reduce(Expression source, String to) {

return Money.dollar(10);

}


Зеленая полоса! Теперь мы готовы выполнить рефакторинг. Но сначала подведем итоги главы. В этой главе мы

• вместо большого теста реализовали меньший тест, чтобы добиться быстрого прогресса (вместо операции $5 + 1 °CHF ограничились более простой операцией $5 + $5);

• основательно обдумали возможные метафоры для нашего предполагаемого дизайна;

• переписали первоначальный тест в свете новой метафоры;

• как можно быстрее добились компиляции теста;

• добились успешного выполнения теста;

• с трепетом посмотрели вперед, оценив объем рефакторинга, который необходим, чтобы сделать реализацию реальной.

7 В переводе на русский язык sum – это сумма. – Примеч. пер.

13. Делаем реализацию реальной

$5 + 1 °CHF = $10, если курс обмена 2:1

$5 + $5 = $10


Мы не можем вычеркнуть пункт $5 + $5, пока не удалим из кода все повторяющиеся фрагменты. Внимательно рассмотрим код. В нем нет повторяющегося кода, но есть повторяющиеся данные – $10 в «поддельной» реализации:


Bank

Money reduce(Expression source, String to) {

return Money.dollar(10);

}


Это выражение по своей сути дублирует выражение $5 + $5 в коде теста:


public void testSimpleAddition() {

Money five = Money.dollar(5);