Экстремальное программирование. Разработка через тестирование | страница 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, обладают только конструкторами, однако конструктор – это недостаточная причина для создания подкласса. Мы должны избавиться от бесполезных подклассов.