Читаем Экстремальное программирование. Разработка через тестирование полностью

Я использую выделение метода, чтобы избавиться от дублирования, когда вижу, что два метода обладают сходными участками кода. В этом случае я выделяю схожие участки в отдельный метод. (Браузер рефакторинга для Smalltalk – Refactoring Browser – выполняет еще более полезную задачу: он просматривает код в поисках метода, аналогичного коду, который вы намерены выделить, и в случае, если такой метод уже есть, предлагает использовать уже существующий метод вместо того, чтобы создавать новый.)

Разделение методов на множество мелких кусочков может зайти слишком далеко. Если я не вижу, куда идти дальше, я часто использую шаблон «Встраивание метода» (Inline Method), чтобы собрать код в одном месте и увидеть новый, более удобный способ разделения.

Встраивание метода (Inline Method)

Как можно упростить код, если становится сложно уследить за последовательностью передачи управления от метода к методу? Замените обращение к методу кодом этого метода.

Как

1. Скопируйте код метода в буфер обмена.

2. Вставьте код метода вместо обращения к методу.

3. Замените все формальные параметры фактическими. Если, например, вы передаете reader.getNext(), то есть выражение, обладающее побочным эффектом, будьте осторожны и присвойте полученное значение временной переменной.

Зачем

Один из моих рецензентов пожаловался на сложность кода в первой части книги, который требует от объекта Bank преобразовать объект Expression в объект Money.

public void testSimpleAddition() {

Money five = Money.dollar(5);

Expression sum = five.plus(five);

Bank bank = new Bank();

Money reduced = bank.reduce(sum, "USD");

assertEquals(Money.dollar(10), reduced);

}

«Это слишком сложно. Почему бы не реализовать преобразование в самом объекте Money?» Ну что же, поставим эксперимент. Как это сделать? Давайте встроим метод Bank.reduce() и посмотрим, как это будет выглядеть:

public void testSimpleAddition() {

Money five = Money.dollar(5);

Expression sum = five.plus(five);

Bank bank = new Bank();

Money reduced = sum.reduce(bank, «USD»);

assertEquals(Money.dollar(10), reduced);

}

Возможно, вторая версия понравится вам больше, возможно, нет. Важно понимать, что при помощи шаблона «Встраивание метода» (Inline Method) вы можете экспериментировать с последовательностью выполнения действий. Когда я выполняю рефакторинг, я формирую у себя в голове мысленную картину системы с кусками логики и потоком выполнения программы, перетекающим от одного объекта к другому объекту. Когда мне кажется, что я вижу нечто многообещающее, я использую рефакторинг, чтобы попробовать это и увидеть результат.

В разгаре битвы я могу вдруг обнаружить, что попался в ловушку собственной гениальности. (Не буду говорить, насколько часто это происходит.) Когда это происходит, я использую «Встраивание метода» (Inline Method), чтобы разобраться в той путанице, которую я создал: «Так, этот объект обращается к этому, этот к этому… не могу понять, что же здесь происходит?» Я встраиваю несколько уровней абстракции и смотрю, что же на самом деле происходит. После этого я могу заново выделить абстракцию, использовав более удобный способ.

Выделение интерфейса (Extract Interface)

Как создать альтернативные реализации операций в языке Java? Создайте интерфейс, в котором будут содержаться общие операции.

Как

1. Напишите объявление интерфейса. Иногда в качестве имени интерфейса используется имя существующего класса. В этом случае вы должны предварительно переименовать класс.

2. Сделайте так, чтобы существующий класс реализовывал объявленный вами интерфейс.

3. Добавьте в интерфейс все обязательные методы. В случае необходимости измените режим видимости методов класса.

4. Там, где это возможно, измените объявления с класса на интерфейс.

Зачем

Иногда необходимость выделения интерфейса возникает в случае, когда вы переходите от одной реализации к другой. Например, у вас есть класс Rectangle (прямоугольник), и вы хотите создать класс Oval (овал) – в этом случае вы создаете интерфейс Shape (фигура). В подобных ситуациях подобрать имя для интерфейса, как правило, несложно. Однако иногда приходится изрядно помучиться, прежде чем обнаружится подходящая метафора.

Иногда, когда нужно выделить интерфейс, вы используете шаблон «Тестирование обработки ошибок» (Crash Test Dummy) или «Поддельный объект» (Mock Object). В этом случае подбор подходящего имени выполняется сложнее, так как в вашем распоряжении лишь один пример использования интерфейса. В подобных случаях у меня возникает соблазн наплевать на информативность и назвать интерфейс IFile, а реализующий его класс – File. Однако я приучил себя останавливаться на мгновение и размышлять о том, достаточно ли хорошо я понимаю то, над чем работаю? Возможно, интерфейс лучше назвать File, а реализующий его класс – DiskFile, так как соответствующая реализация основана на том, что данные, содержащиеся в файле, хранятся на жестком диске.

Перемещение метода (Move Method)
Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги