Экстремальное программирование. Разработка через тестирование - [11]

Шрифт
Интервал

1. Написать тест.

2. Добиться его безошибочной компиляции.

3. Запустить тест и убедиться, что он потерпел неудачу.

4. Добиться успешного выполнения теста.

5. Устранить дублирование.

На разных этапах решаются разные задачи, преследуются разные цели. То, что совершенно недопустимо для одного из этапов, может быть вполне приемлемым для другого этапа. Однако в целом методика TDD работает только в случае, если ни один из этапов не упущен. Если вы пропустите хотя бы одно звено, развалится вся цепочка.

Первые три фазы цикла разработки TDD должны выполняться как можно быстрее. Определяющая характеристика этих этапов – скорость. На этих этапах в жертву скорости можно принести очень многое, в том числе чистоту дизайна. Честно говоря, сейчас я несколько волнуюсь. Я только что разрешил вам забыть о принципах хорошего дизайна. Представляю, как вы приходите к своим коллегам, подчиненным и во всеуслышание объявляете: «Кент сказал, что все эти разговоры про хороший дизайн – полная ерунда!» Остановитесь. Цикл еще не закончен. Четырехногий уродец из благородного семейства пятиногих стульев вечно падает. Первые четыре шага нашего цикла не работают без пятого. Хороший дизайн в подходящее время! Сначала сделаем, чтобы код заработал, потом сделаем, чтобы код был правильным (make it run, make it right).

Теперь мне стало легче. Теперь я уверен, что до тех пор, пока вы не избавитесь от дублирования, вы не покажете свой код никому за исключением своего партнера по паре. На чем мы остановились? Ах, да. Забываем о принципах хорошего дизайна в угоду скорости (мы будем заниматься искуплением этого греха на протяжении нескольких следующих глав).


Franc

class Franc {

private int amount;

Franc(int amount) {

this.amount = amount;

}


Franc times(int multiplier) {

return new Franc(amount * multiplier);

}


public boolean equals(Object object) {

Franc franc = (Franc) object;

return amount == franc.amount;

}

}

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

$5 * 2 = $10

Сделать переменную amount закрытым (private) членом

Побочные эффекты в классе Dollar?

Округление денежных величин?

equals()

hashCode()

Равенство значению null

Равенство объектов

5 CHF * 2 = 1 °CHF

Дублирование Dollar/Franc

Общие операции equals()

Общие операции times()


Чтобы запустить код, нам не потребовалось прикладывать каких-либо усилий, поэтому мы смогли «перепрыгнуть» через этап «добиться безошибочной компиляции кода» (Make it compile).

Зато теперь в нашем коде полно повторяющихся фрагментов. Прежде чем приступить к разработке следующего теста, мы должны избавиться от дублирования. Думаю, что следует начать с обобщения метода equals(). Однако об этом в следующей главе. На текущий момент мы можем вычеркнуть из нашего списка еще один пункт, однако вместе с этим нам придется добавить в него два дополнительных пункта.

В данной главе мы

• решили отказаться от создания слишком большого теста и вместо этого создали маленький, чтобы обеспечить быстрый прогресс;

• создали код теста путем бесстыдного копирования и редактирования;

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

• дали себе обещание ни в коем случае не уходить домой до тех пор, пока не устраним дублирование.

6. Равенство для всех, вторая серия

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

$5 * 2 = $10

Сделать переменную amount закрытым (private) членом

Побочные эффекты в классе Dollar?

Округление денежных величин?

equals()

hashCode()

Равенство значению null

Равенство объектов

5 CHF * 2 = 1 °CHF

Дублирование Dollar/Franc


Общие операции equals()

Общие операции times()


В книге Crossing to Safety автор Вэлленц Стегнер (Wallance Stegner) описывает рабочее место одного из персонажей. Каждый инструмент находится на предназначенном для него месте, пол чисто вымыт и подметен, повсюду превосходный порядок и чистота. Однако чтобы добиться подобного положения вещей, персонаж не делал никаких специальных подготовительных процедур. «Подготовка была делом всей его жизни. Он подготавливался, затем убирался на рабочем месте». (Конец книги заставил меня громко рассмеяться в бизнес-классе трансатлантического «Боинга-747». Так что если решите ее прочитать, читайте с осторожностью.)

В главе 5 мы добились успешного выполнения теста. Это значит, что требуемая функциональность реализована. Однако чтобы сделать это быстро, нам пришлось продублировать огромный объем кода. Теперь пришло время убрать за собой.

Мы можем сделать так, чтобы один из разработанных нами классов стал производным от другого. Я попробовал сделать это, однако понял, что в этом случае ничего не выигрываю. Вместо этого удобнее создать суперкласс, который станет базовым для обоих разработанных нами классов. Ситуация проиллюстрирована на рис. 6.1. (Я уже пробовал так поступить и пришел к выводу, что это именно то, что нужно, однако придется приложить усилия.)


Рис. 6.1. Общий суперкласс для двух разработанных нами классов


Для начала попробуем реализовать в базовом классе Money общий для обоих производных классов метод equals(). Начнем с малого:


Money

class Money


Запустим тесты – они по-прежнему выполняются. Конечно же, мы пока не сделали ничего такого, что нарушило бы выполнение наших тестов, однако в любом случае лишний раз запустить тесты не помешает. Теперь попробуем сделать класс Dollar производным от класса Money:


Рекомендуем почитать
Язык PL/SQL

В учебно-методическом пособии рассматриваются основы языка программирования PL/SQL, реализованного в системе управления базами данных Oracle Database Server. Приводятся сведения о поддерживаемых типах данных, структуре программ PL/SQL и выполнении SQL-предложений в них. Отдельно рассмотрено создание хранимых в базах данных Oracle программ PL/SQL – процедур, функций, пакетов и триггеров.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Системное программное обеспечение. Лабораторный практикум

В книге рассматриваются базисные теоретические основы, необходимые для построения компиляторов, основные технологические приемы и методы их реализации. В ней приведены различные варианты заданий для выполнения лабораторного практикума по курсу «Системное программное обеспечение», а также примеры выполнения этих заданий. В каждом примере подробно рассматриваются все особенности его выполнения, как на этапе подготовки необходимой математической базы, так и на этапе программной реализации. В лабораторных работах автор обращает внимание на основные сложности, связанные с ее выполнением, а также на возможные типичные ошибки и недочеты, дает рекомендации по возможностям программной реализации, отличным от кода, приводимого в примерах.Книга ориентирована на студентов, обучающихся в технических вузах по специальностям, связанным с вычислительной техникой.


Программирование на языке Пролог для искусственного интеллекта

Книга известного специалиста по программированию (Югославия), содержащая основы языка Пролог и его приложения для решения задач искусственного интеллекта. Изложение отличается методическими достоинствами — книга написана в хорошем стиле, живым языком. Книга дополняет имеющуюся на русском языке литературу по языку Пролог.Для программистов разной квалификации, специалистов по искусственному интеллекту, для всех изучающих программирование.


Программирование на Visual C++. Архив рассылки

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.


Язык программирования С# 2005 и платформа .NET 2.0.

В этой книге содержится описание базовых принципов функционирования платформы .NET, системы типов .NET и различных инструментальных средств разработки, используемых при создании приложений .NET. Представлены базовые возможности языка программирования C# 2005, включая новые синтаксические конструкции, появившиеся с выходом .NET 2.0, а также синтаксис и семантика языка CIL. В книге рассматривается формат сборок .NET, библиотеки базовых классов .NET. файловый ввод-вывод, возможности удаленного доступа, конструкция приложений Windows Forms, доступ к базам данных с помощью ADO.NET, создание Web-приложений ASP.NET и Web-служб XML.