Я никогда не думал, что метафора – это настолько мощный инструмент. Многие думают, что метафора – это всего лишь источник имен. Разве не так? Похоже, что нет.
Для представления «комбинации нескольких денежных величин, которые могут быть выражены в разных валютах», Уорд Каннингэм использовал метафору вектора . Имеется в виду математический вектор – набор коэффициентов, каждому из которых соответствует некоторая валюта. Лично я некоторое время использовал метафору суммы денег (MoneySum), затем придумал денежный мешок (MoneyBag) – звучит понятно и близко к реальности, – наконец, остановился на метафоре бумажника (Wallet). Что такое бумажник и как он функционирует, известно абсолютно всем. Все эти метафоры подразумевают, что набор денежных значений (объектов Money) является плоским. Иначе говоря, выражение 2 USD + 5 CHF + 3 USD эквивалентно выражению 5 USD + 5 CHF. Два значения в одной и той же валюте автоматически сливаются в одно.
Метафора математического выражения избавила меня от множества неприятных проблем, связанных со слиянием дублирующихся валют. Результирующий код получился чище, чем я когда-либо видел. Конечно же, я несколько обеспокоен производительностью кода, основанного на подобной метафоре, однако, прежде чем приступать к оптимизации, я намерен проанализировать статистику обращений к различным участкам кода.
Почему я был вынужден переписать заново то, что я уже писал до этого не меньше 20 раз? Буду ли я и дальше сталкиваться с подобными сюрпризами? Существует ли способ, который позволит мне найти правильное решение, по крайней мере в течение первых трех попыток? А может быть, этот способ позволит мне найти правильное решение с первой попытки?
Использование JUnit
Я поручил инфраструктуре JUnit вести журнал в процессе разработки мультивалютного примера. Выяснилось, что за все время я нажал клавишу Enter ровно 125 раз. Оценку интервала между запусками тестов нельзя считать достоверной, так как в ходе работы я не только программировал, но и писал текст книги. Однако когда я занимался только программированием, я запускал тесты приблизительно раз в минуту.
На рис. 17.1 представлена гистограмма интервалов между запусками тестов. Большое количество длительных интервалов, скорее всего, обусловлено тем, что я тратил значительное время на написание текста книги.
Рис. 17.1.Гистограмма интервалов времени между запусками тестов
Метрики кода
В табл. 17.1 приводятся некоторые статистические данные, характеризующие код.
Таблица 17.1.Метрики кода
Вот некоторые примечания к данной таблице:
1. Мы не реализовали весь программный интерфейс (API) целиком, поэтому не можем достоверно оценить полное количество функций, или количество функций на один класс, или количество строк кода на один класс. Однако соотношения этих параметров можно считать поучительными. Количество функций и количество строк в тестах приблизительно такое же, как и в функциональном коде.
2. Количество строк кода в тестах можно сократить, если извлечь из кода операции подготовки тестовых данных. Однако общее соотношение между строками функционального кода и строками тестирующего кода при этом сохранится.
3. Цикломатическая сложность (cyclomatic complexity) – это величина, характеризующая сложность обычного потока управления в программе. Цикломатическая сложность тестов равна 1, так как в тестирующем коде нет ни ветвлений, ни циклов. Цикломатическая сложность функционального кода близка к единице, так как вместо явных ветвлений для передачи управления чаще используется полиморфизм.
4. Оценка количества строк в функции дана с учетом заголовка функции и закрывающей скобки.
5. Количество строк на функцию для тестирующего кода в нашем случае больше чем могло бы быть, так как мы не выделили общий код в отдельные функции. Об этом рассказывается в главе 29, которая посвящена методам работы с xUnit.
Процесс
Цикл TDD выглядит следующим образом:
• написать тест;
• запустить все тесты и убедиться, что добавленный тест терпит неудачу;
• внести в код изменения;
• запустить тесты и убедиться, что все они выполнились успешно;
Читать дальше
Конец ознакомительного отрывка
Купить книгу