теперь вместо private используем мод ификатор д о ступа protected. В
противном случае под класс не сможет обратиться к этой переменной.
(Если бы мы хотели
д вигаться еще мед леннее, мы могли бы на первом
шаге объявить переменную в классе Money, а на втором шаге уд алить ее
объявление из класса
Dollar, од нако я решил д ействовать смело и
решительно.)
Теперь можно переместить код метод а equals() вверх по иерархии
классов, то есть в класс Money. Прежд е
всего мы изменим объявление
временной переменной:
Dollar
public boolean equals(Object object) {
Money
dollar = (Dollar) object;
return amount == dollar.amount;
}
Все тесты по-прежнему работают. Теперь попробуем изменить
привед ение типа.
Dollar
public boolean equals(Object object) {
Money dollar = (
Money
) object;
return amount == dollar.amount;
}
Чтобы исход ный код получился более о смысленным, изменим имя
временной переменной:
Dollar
public boolean equals(Object object) {
Money
money
= (Money) object;
return amount ==
money
.amount;
}
Теперь переместим метод из класса Dollar в класс Money:
Money
public boolean equals(Object object) {
Money money= (Money) object;
return amount == money.amount;
}
Теперь настало время уд алить метод Franc.equals(). Прежд е всего мы
обнаруживаем, что у нас д о сих пор нет теста, проверяющего равенство
д вух объектов класса Franc, – когд а мы,
о собо не разд умывая,
д ублировали код класса Dollar, мы нагрешили еще больше, чем д умали.
Поэтому, прежд е чем мод ифицировать код , мы д олжны написать все
необход имые тесты.
В ближайшем буд ущем,
скорее всего, вам прид ется использовать
под ход TDD в отношении код а, который не сопровожд ается
д о статочным количеством тестов. В отсутствие ад екватного набора
тестов
любой
рефакторинг
может
привести
к
нарушению
работо спо собно сти код а.
Иными словами, в ход е рефакторинга можно
д опустить ошибку, при этом все имеющиеся тесты буд ут выполняться
как ни в чем не бывало. Ошибка может вскрыться слишком позд но, а ее
устранение может стоить слишком д орого. Что же д елать?
Прежд е чем что-либо менять в код е, вы д олжны написать все
тесты, которые кажутся вам необход имыми. Если этого не сд елать, рано
или позд но,
выполняя рефакторинг, вы чего-нибуд ь поломаете. Код
перестанет работать так, как д олжен. Вы потратите кучу времени на
поиск ошибки и сформируете пред убежд ение против рефакторинга.
Если под обный инцид ент повторится, вы можете вообще перестать
д елать рефакторинг. Дизайн начнет д еград ировать. Вас уволят с работы.
От вас уйд ет ваша любимая собака. Вы
перестанете мыться и чистить
зубы. У вас начнется кариес. Чтобы сохранить зубы зд оровыми, всегд а
сначала пишите тесты и только по сле этого выполняйте рефакторинг.
К счастью, в нашем случае написать тесты совсем несложно. Для
этого д о статочно скопировать и немножко отред актировать тесты д ля
класса Dollar:
public void testEquality() {
assertTrue(new Dollar(5). equals(new Dollar(5)));
assertFalse(new Dollar(5). equals(new Dollar(6)));
assertTrue(new Franc(5). equals(new Franc(5)));
assertFalse(new Franc(5). equals(new Franc(6)));
}
Снова д ублирование. Целых д ве строчки! Этот грех нам тоже
прид ется искупить. Но чуть позже.
Теперь,
когд а тесты на месте, мы можем сд елать класс Franc
производ ным от класса Money:
Franc
class Franc extends Money {
private int amount;
}
Далее мы можем уничтожить поле amount в классе Franc, так как
это значение буд ет храниться в од ноименном поле класса Money:
Franc
class Franc extends Money {
}
Метод Franc.equals() выгляд ит фактически так же,
как и метод
Money.equals(). Сд елав их абсолютно од инаковыми, мы сможем уд алить
реализацию этого метод а из класса Franc. При этом смысл нашей
программы не изменится. Для начала изменим объявление временной
переменной:
Do'stlaringiz bilan baham: