Экстремальное программирование. Разработка через тестирование | страница 33
public void testDifferentClassEquality() {
assertTrue(new Money(10, "CHF"). equals(new Franc(10, "CHF")));
}
Как и ожидалось, тест потерпел неудачу. Код метода equal() должен сравнивать идентификаторы валют, а не имена классов:
Money
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount
&& currency(). equals(money.currency());
}
Теперь метод Franc.times() может возвращать значение Money, и все тесты будут по-прежнему успешно выполняться:
Franc
Money times(int multiplier) {
return new Money(amount * multiplier, currency);
}
Сработает ли этот трюк для метода Dollar.times()?
Dollar
Money times(int multiplier) {
return new Money (amount * multiplier, currency);
}
Да! Теперь две реализации абсолютно идентичны, и мы можем переместить их в базовый класс.
Money
Money times(int multiplier) {
return new Money(amount * multiplier, currency);
}
$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()?
Метод умножения там, где ему следует быть, теперь мы готовы удалить ненужные нам производные классы.
В данной главе мы
• сделали идентичными две реализации метода times(), для этого мы избавились от вызовов фабричных методов в них, и заменили константы переменными;
• добавили в класс отладочный метод toString() без теста;
• попробовали модифицировать код (заменили тип Franc возвращаемого значения на Money) и обратились к тестам, чтобы узнать, сработает ли это;
• отменили изменения и написали еще один тест, добились успешного выполнения теста и вновь применили изменения.
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, обладают только конструкторами, однако конструктор – это недостаточная причина для создания подкласса. Мы должны избавиться от бесполезных подклассов.