Книга: Экстремальное программирование. Разработка через тестирование
11. Корень всего зла
11. Корень всего зла
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 * 2 = $10
Сделать переменную amount закрытым (private) членом
Побочные эффекты в классе Dollar?
Округление денежных величин?
equals()
hashCode()
Равенство значению null
Равенство объектов
5 CHF * 2 = 1 °CHF
Дублирование Dollar/Franc
Общие операции equals()
Общие операции times()
Сравнение франков (Franc) и долларов (Dollar)
Валюта?
Нужен ли тест testFrancMultiplication()?
Два производных класса, Dollar и Franc, обладают только конструкторами, однако конструктор – это недостаточная причина для создания подкласса. Мы должны избавиться от бесполезных подклассов.
Ссылки на подклассы можно заменить ссылками на суперкласс, не изменив при этом смысл кода. Начнем с класса Franc:
Franc
static Money franc(int amount) {
return new Money (amount, «CHF»);
}
Затем перейдем к классу Dollar:
Dollar
static Money dollar(int amount) {
return new Money (amount, «USD»);
}
Ссылок на класс Dollar больше нет, поэтому мы можем удалить этот класс. Однако в только что написанном нами тесте есть одна ссылка на класс Franc:
public void testDifferentClassEquality() {
assertTrue(new Money(10, "CHF"). equals(new Franc(10, "CHF")));
}
Если равенство объектов достаточно хорошо протестировано другими тестами, значит, мы можем безбоязненно удалить этот тест. Давайте взглянем на другие тесты:
public void testEquality() {
assertTrue(Money.dollar(5). equals(Money.dollar(5)));
assertFalse(Money.dollar(5). equals(Money.dollar(6)));
assertTrue(Money.franc(5). equals(Money.franc(5)));
assertFalse(Money.franc(5). equals(Money.franc(6)));
assertFalse(Money.franc(5). equals(Money.dollar(5)));
}
Похоже, что все возможные случаи определения равенства достаточно полно охвачены другими тестами. Я даже сказал бы, что тестов слишком много. Мы можем удалить третье и четвертое выражение assert, так как они дублируют первое и второе:
public void testEquality() {
assertTrue(Money.dollar(5). equals(Money.dollar(5)));
assertFalse(Money.dollar(5). equals(Money.dollar(6)));
assertFalse(Money.franc(5). equals(Money.dollar(5)));
}
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 * 2 = $10
Сделать переменную amount закрытым (private) членом
Побочные эффекты в классе Dollar?
Округление денежных величин?
equals()
hashCode()
Равенство значению null
Равенство объектов
5 CHF * 2 = 1 °CHF
Дублирование Dollar/Franc
Общие операции equals()
Общие операции times()
Сравнение франков (Franc) и долларов (Dollar)
Валюта?
Нужен ли тест testFrancMultiplication()?
Тест testDifferentClassEquality() служит доказательством того, что, сравнивая объекты, мы сравниваем различные валюты, но не различные классы. Этот тест имеет смысл только в случае, если в программе существует несколько различных классов. Однако мы уже избавились от класса Dollar и намерены точно так же избавиться от класса Franc. Иными словами, в нашем распоряжении останется только один денежный класс: Money. С учетом наших намерений, тест testDifferentClassEquality() оказывается для нас излишней обузой. Мы удалим его, а затем избавимся от класса Franc.
Обратите также внимание, что в программе присутствуют отдельные тесты для проверки умножения франков на доллары. Если заглянуть в код, можно увидеть, что на текущий момент логика метода, реализующего умножение, не зависит от типа валюты (зависимость была бы только в случае, если бы мы использовали два различных класса). То есть мы можем удалить функцию testFrancMultiplication(), не опасаясь, что потеряем уверенность в правильности работы системы.
Итак, в нашем распоряжении единый денежный класс, и мы готовы приступить к реализации сложения.
Но сначала подведем итоги. В этой главе мы
• закончили потрошить производные классы и избавились от них;
• удалили тесты, которые имели смысл только при использовании старой структуры кода, но оказались избыточными в коде с новой структурой.
- 1. Мультивалютные деньги
- 2. Вырождающиеся объекты
- 3. Равенство для всех
- 4. Данные должны быть закрытыми
- 5. Поговорим о франках
- 6. Равенство для всех, вторая серия
- 7. Яблоки и апельсины
- 8. Создание объектов
- 9. Потребность в валюте
- 10. Избавление от двух разных версий times()
- 11. Корень всего зла
- 12. Сложение, наконец-то
- 13. Делаем реализацию реальной
- 14. Обмен валюты
- 15. Смешение валют
- 16. Абстракция, наконец-то!
- 17. Ретроспектива денежного примера
- Удаление учебного узла
- Навигация по иерархии узла
- Управление пользователями и разрешениями узла
- Смена темы узла
- Сохранение и использование шаблона узла
- Управление функциями узла
- Удаление узла
- Исчезла Панель задач – нет часов, свернутых программ, кнопки Пуск
- На Панели быстрого запуска возле кнопки меню Пуск вмещается всего три значка. Как увеличить ее емкость?
- У меня новый SATA-винчестер на 160 Гбайт, однако Windows XP определяет всего 120 Гбайт. Куда пропали остальные 40 Гбайт?
- Использование начального узла
- С помощью какой программы лучше всего записывать фильмы на компакт-диски?