Читаем Экстремальное программирование: Разработка через тестирование полностью

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);

Expression sum = five.plus(five);

Bank bank = new Bank();

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

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

}


Раньше, если у нас имелась «поддельная» реализация, для нас было очевидным, как можно вернуться назад и сформировать реальную реализацию. Для этого достаточно было заменить константы переменными. Однако в данном случае пока не понимаю, как вернуться назад. Поэтому, несмотря на некоторый риск, я решаю двигаться вперед:


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

$5 + $5 = $10

Операция $5 + $5 возвращает объект Money


Прежде всего, метод Money.plus() должен возвращать не просто объект Money, а реальное выражение (Expression), то есть сумму (Sum). (Возможно, в будущем мы оптимизируем специальный случай сложения двух одинаковых валют, однако это произойдет позже.)


Итак, в результате сложения двух объектов Money должен получиться объект класса Sum:


public void testPlusReturnsSum() {

Money five = Money.dollar(5);

Expression result = five.plus(five);

Sum sum = (Sum) result;

assertEquals(five, sum.augend);

assertEquals(five, sum.addend);

}


(Вы когда-нибудь слышали, что в английском языке первое слагаемое обозначается термином augend, а второе слагаемое – термином addend? Об этом не слышал даже автор до тех пор, пока не приступил к написанию данной книги.)

Только что написанный тест, скорее всего, проживет недолго. Дело в том, что он сильно связан с конкретной реализацией разрабатываемой нами операции и мало связан с видимым внешним поведением этой операции. Однако, заставив его работать, мы окажемся на шаг ближе к поставленной цели. Чтобы скомпилировать тест, нам потребуется класс Sum с двумя полями: augend и addend:


Sum

class Sum {

Money augend;

Money addend;

}


В результате получаем исключение преобразования классов (ClassCastException) – метод Money.plus() возвращает объект Money, но не объект Sum:


Money

Expression plus(Money addend) {

return new Sum(this, addend);

}


Класс Sum должен иметь конструктор:


Sum

Sum(Money augend, Money addend) {

}


Кроме того, класс Sum должен поддерживать интерфейс Expression:


Sum

class Sum implements Expression


Наша система компилируется, однако тесты терпят неудачу – это из-за того, что конструктор класса Sum не присваивает значений полям (мы могли бы создать «поддельную» реализацию, инициализировав поля константами, однако я обещал двигаться быстрее):


Sum

Sum(Money augend, Money addend) {

this.augend = augend;

this.addend = addend;

}


Теперь в метод Bank.reduce() передается объект класса Sum. Если суммируются две одинаковые валюты и целевая валюта совпадает с валютой обоих слагаемых, значит, результатом будет объект класса Money, чье значение будет равно сумме значений двух слагаемых:


public void testReduceSum() {

Expression sum = new Sum(Money.dollar(3), Money.dollar(4));

Bank bank = new Bank();

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

assertEquals(Money.dollar(7), result);

}


Я тщательно выбираю значения параметров так, чтобы нарушить работу существующего теста. Когда мы приводим (метод reduce()) объект класса Sum к некоторой валюте, в результате (с учетом упомянутых упрощенных условий) должен получиться объект класса Money, чье значение (amount) совпадает с суммой значений двух объектов Money, переданных конструктору объекта Sum, а валюта (currency) совпадает с валютой обоих этих объектов:


Bank

Money reduce(Expression source, String to) {

Sum sum = (Sum) source;

int amount = sum.augend.amount + sum.addend.amount;

return new Money(amount, to);

}


Код выглядит уродливо по двум причинам:

Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги

Как справиться с компьютерной зависимостью
Как справиться с компьютерной зависимостью

Компьютер так прочно вошел в нашу жизнь, что большая половина человечества не может представить без него своего существования. Мы проводим за ним не только все рабочее, но и свободное время. Однако не каждый человек знает, что круглосуточное пребывание за монитором несет реальную угрозу как физическому (заболевания позвоночника, сердечно-сосудистой системы и т. д.), так и психическому здоровью (формирование психической зависимости от Интернета и компьютерных игр). С помощью данной книги вы сможете выявить у себя и своих близких признаки компьютерной зависимости, понять причины и механизмы ее возникновения и справиться с ней посредством новейших психологических методик и упражнений.

Виктория Сергеевна Тундалева , Елена Вячеславовна Быковская , М О Носатова , Н Р Казарян , Светлана Викторовна Краснова

Зарубежная компьютерная, околокомпьютерная литература / Прочая компьютерная литература / Книги по IT
Компьютер в помощь астрологу
Компьютер в помощь астрологу

Книга поможет овладеть основами астрологии и научит пользоваться современными программами для астрологических расчетов. На понятном обычному человеку уровне дано объяснение принципов и идеологии астрологии «докомпьютерных» времен. Описана техника работы с программами, автоматизирующими сложные астрологические расчеты. Рассмотрены основные инструменты практикующего астролога: программы семейства Uranus для новичков, ZET 8 и Stalker — для специалистов, Almagest — для экспертов. Для всех этих программ дано развернутое описание интерфейса и приведены инструкции расчета гороскопов различного типа. Изложены методы интерпретации гороскопов с помощью компьютера. Все астрологические расчеты приведены в виде подробных пошаговых процедур, которые позволят даже начинающему получать астрологические результаты профессионального уровня. Прилагаемый компакт-диск содержит видеокурс по работе с популярными астропроцессорами.Для широкого круга пользователей.

А. Г. Жадаев , Александр Геннадьевич Жадаев

Зарубежная компьютерная, околокомпьютерная литература / Прочая компьютерная литература / Книги по IT