1 ...8 9 10 12 13 14 ...82 $5 + 1 °CHF = $10, если курс обмена 2:1
$5 * 2 = $10
Сделать переменнуюamount закрытым членом класса
Побочные эффекты в классе Dollar?
Округление денежных величин?
equals()
hashCode()
Равенство значению null
Равенство объектов
Итак, сейчас операция проверки равенства реализована полностью. Но как учесть сравнение со значением null и сравнение c другими объектами? Это часто используемые операции, пока они нам еще не нужны, поэтому мы просто добавим их в список задач.
Теперь, когда у нас есть операция проверки равенства, можно напрямую сравнивать объекты Dollar. Это позволит нам сделать переменную amount закрытой, какой и должна быть добропорядочная переменная экземпляра. Резюмируем все вышесказанное:
• поняли, что для использования шаблона проектирования «Объект-значение» необходимо реализовать операцию проверки равенства;
• создали тест для этой операции;
• реализовали ее простейшим способом;
• продолжили тестирование (вместо того, чтобы сразу приступить к рефакторингу);
• выполнили рефакторинг так, чтобы охватить оба теста сразу.
4. Данные должны быть закрытыми
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 * 2 = $10
Сделать переменную amount закрытым членом класса
Побочные эффекты в классе Dollar?
Округление денежных величин?
equals()
hashCode()
Равенство значению null
Равенство объектов
Теперь, когда определена операция проверки равенства, с ее помощью можно повысить наглядность тестов. По идее, метод Dollar.times() должен возвращать новый объект Dollar, величина которого равна величине исходного объекта (метод которого мы вызываем), умноженной на коэффициент. Однако наш тест не показывает этого явно:
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product = five.times(2);
assertEquals(10, product.amount);
product = five.times(3);
assertEquals(15, product.amount);
}
Мы можем переписать первую проверку и сравнить в ней объекты Dollar:
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product = five.times(2);
assertEquals(new Dollar(10), product);
product = five.times(3);
assertEquals(15, product.amount);
}
Выглядит неплохо, поэтому перепишем и вторую проверку:
public void testMultiplication() {
Dollar five = new Dollar(5);
Dollar product = five.times(2);
assertEquals(new Dollar(10), product);
product = five.times(3);
assertEquals(new Dollar(15), product);
}
Теперь нам не нужна вспомогательная переменная product, поэтому устраним ее:
public void testMultiplication() {
Dollar five= new Dollar(5);
assertEquals(new Dollar(10), five.times(2));
assertEquals(new Dollar(15), five.times(3));
}
Согласитесь, этот вариант теста значительно нагляднее.
Учтем внесенные изменения. Теперь только класс Dollar использует переменную экземпляра amount, поэтому мы можем сделать ее закрытой:
Dollar
private int amount;
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 * 2 = $10
Сделать переменную amount закрытым членом класса
Побочные эффекты в классе Dollar?
Округление денежных величин?
equals()
hashCode()
Равенство значению null
Равенство объектов
Вычеркиваем еще один пункт из списка задач. Заметьте, мы подвергли себя риску: если тест, проверяющий равенство, не смог бы точно определить корректность операции сравнения, тогда и тест умножения не смог бы проверить, правильно ли оно работает. В TDD принято активное управление риском. Мы не гонимся за совершенством. Выражая все двумя способами – тестами и кодом, – мы надеемся уменьшить дефекты настолько, чтобы уверенно идти дальше. Время от времени наши рассуждения будут нас подводить, позволяя появляться ошибкам. Когда это случится, мы вспомним урок о том, что надо написать тест и двигаться дальше. Все остальное время мы отважно продвигаемся вперед под победно развевающейся зеленой полоской нашего индикатора (вообще-то мой индикатор не развевается, но я люблю помечтать).
Подведем итоги:
• использовали только что разработанную функциональность для улучшения теста;
• заметили, что, если одновременно два теста терпят неудачу, наши дела плохи;
• продолжили несмотря на риск;
• использовали новую функциональность тестируемого объекта для уменьшения зависимости между тестами и кодом.
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 * 2 = $10
Сделать переменную amount закрытым (private) членом
Побочные эффекты в классе Dollar?Округление денежных величин?
equals()
hashCode()
Равенство значению null
Равенство объектов
5 CHF * 2 = 1 °CHF
Можем ли мы приступить к реализации первого, самого интересного теста в данном списке? Мне все еще кажется, что это будет слишком большой шаг. Я не представляю себе, как можно написать этот тест за один маленький шажок. Мне кажется, что вначале необходимо создать объект наподобие Dollar, который соответствовал бы не долларам, а франкам. Пусть это будет объект с названием Franc. Для начала объект Franc может функционировать в точности как объект Dollar – если у нас будет такой объект, нам будет проще размышлять о реализации теста, связанного со смешанным сложением двух разных валют.
Читать дальше
Конец ознакомительного отрывка
Купить книгу