Кент Бек

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


Скачать книгу

что даже не заметили. Произведение «5 умножить на 2» присутствует как в тесте, так и в тестируемом коде. Только изначально в коде оно было представлено в виде константы 10. Сейчас же 5 и 2 отделены друг от друга, и мы должны безжалостно устранить дублирование, перед тем как двинуться дальше. Такие вот правила.

      Действия, с помощью которого мы устранили бы 5 и 2 за один шаг, не существует. Но что, если переместить установку поля (переменной) amount в метод times()?

      Dollar

      int amount;

      void times(int multiplier) {

      amount= 5 * 2;

      }

      Тест все еще успешно выполняется, и индикатор остался зеленым. Успех нам пока сопутствует.

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

      Оставим рассуждения. На чем мы остановились? Ну да, мы избавлялись от дублирования между кодом теста и рабочим кодом. Где мы можем взять 5? Это значение передавалось конструктору, поэтому его можно сохранить в переменной amount:

      Dollar

      Dollar(int amount) {

      this.amount = amount;

      }

      и использовать в методе times():

      Dollar

      void times(int multiplier) {

      amount = amount * 2;

      }

      Число 2 передается в параметре multiplier, поэтому подставим параметр вместо константы:

      Dollar

      void times(int multiplier) {

      amount= amount * multiplier;

      }

      Чтобы продемонстрировать, как хорошо мы знаем синтаксис языка Java, используем оператор *= (который, кстати, уменьшает дублирование):

      Dollar

      void times(int multiplier) {

      amount *= multiplier;

      }

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

      $5 * 2 = $10

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

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

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

      Теперь можно пометить первый тест как завершенный. Далее мы позаботимся о тех странных побочных эффектах; но сначала давайте подведем итоги. Мы сделали следующее:

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

      • с помощью фрагмента кода описали, какой мы хотим видеть нашу операцию;

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

      • заставили тесты компилироваться, написав соответствующие заготовки;

      • заставили тесты работать, использовав сомнительные приемы;

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

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