Sum(Expression augend, Expression addend) {
this.augend = augend;
this.addend = addend;
}
(Класс Sum начинает напоминать мне шаблон «Компоновщик»
(Composite), од нако еще не настолько, чтобы я захотел обобщить его.) С
классом Sum, пожалуй, закончили, а что насчет
Money?
Аргумент метод а plus() может иметь тип Expression:
Money
Expression plus(Expression addend) {
return new Sum(this, addend);
}
Метод times() может возвращать значение типа Expression:
Money
Expression times(int multiplier) {
return new Money(amount * multiplier, currency);
}
Это означает, что операции plus() и times() д олжны вход ить в со став
интерфейса Expression. С классом Money закончили.
Теперь можно
изменить аргументы метод а plus() в реализации теста:
public void testMixedAddition() {
Money fiveBucks = Money.dollar(5);
Expression
tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Money result = bank.reduce(fiveBucks.plus(tenFrancs), "USD");
assertEquals(Money.dollar(10), result);
}
Объект tenFrancs теперь принад лежит типу Expression, а это значит,
что мы д олжны внести в код некоторые изменения. К счастью,
компилятор под сказывает нам, что именно мы д олжны сд елать. Прежд е
всего вно сим изменение:
public void testMixedAddition() {
Expression
fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Money result = bank.reduce(fiveBucks.plus(tenFrancs), "USD");
assertEquals(Money.dollar(10), result);
}
Компилятор
вежливо сообщает, что plus() не является метод ом
интерфейса Expression. Добавим этот метод в интерфейс:
Expression
Expression plus(Expression addend);
Теперь мы д олжны д обавить этот метод в классы Money и Sum.
Money? Да, этот метод д олжен быть открытым (public) в классе Money:
Money
public Expression plus(Expression addend) {
return new Sum(this, addend);
}
Что
касается класса Sum, про сто д обавим заглушку и отметим
необход имо сть реализации этого метод а в списке зад ач:
Sum
public Expression plus(Expression addend) {
return null;
}
$5 + 1 °CHF = $10, если курс обмена 2:1
$5 + $5 = $10
Операция $5 + $5 возвращает объект Money
Bank.reduce(Money)
Привед ение объекта Money с од новременной конверсией валют
Reduce(Bank,String)
Sum.plus
Expression.times
Теперь программа компилируется и
все тесты выполняются
успешно.
Мы готовы завершить обобщение класса Money д о Expression, но
прежд е, как всегд а, под вед ем краткий итог. В этой главе мы
• за од ин шаг написали необход имый тест и затем мод ифицировали
его, чтобы д обиться успешного его выполнения;
•
выполнили
обобщение
(использовали
более
абстрактное
объявление);
• во спользовались
под сказками компилятора, чтобы внести
изменения (Expression fiveBucks), которые
привели к необход имо сти
д ополнительных изменений (д обавление метод а plus() в интерфейс
Expression и т. п.).