Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы на экзаменационные вопросы по ЭСТП.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
399.63 Кб
Скачать

33. Понятие рефакторинга. Рефакторинги «Встраивание метода», «Выделение интерфейса», «Перемещение метода».

В рамках TDD рефакторинг1 используется интересным образом. Обычно ре­факторинг не может изменить семантику программы ни при каких условиях. В рамках TDD условия семантики формулируются при помощи тестов, которые уже срабатывают. Таким образом, и рамках TDD мы можем, например, заменить константы переменными и с чистой совестью назвать эту процедуру рсфакторин- гом, потому что набор срабатывающих тестов при этом не изменился. Однако на­бор срабатывающих тестов может состоять всего из одного теста. Возможно, семантика программы должна описываться большим количеством тестов. Воз­можно также, что некоторые из этих потенциальных тестов в результате выпол­нения ^факторинга перестали бы срабатывать, если бы они существовали. Одна­ко их пег. поэтому мы о них не беспокоимся.

Отсюда следует, что на программиста, работающею о стиле TDD, возлагается важная обязанность: он должен иметь лопаточное количество тестов» описываю­щих семантику программы. Достаточное по крайней мере настолько, настолько он может судить на момент завершения работы над кодом. Необходимо понимать, что рефакторинг выполняется не с учетом всех существующих тестов, а с учетом всех шзможнмх гсстов. Фраза наподобие: «Я знаю, что там была проблема, но все тесты сработали, поэтому я посчитал код завершенным и интегрировал сто и сис­тему», — не может считаться оправданием. Пишите больше тестов.

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

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

Как

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

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

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

Зачем

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

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

EXTRACT INTERFACE (ВЫДЕЛЕНИЕ ИНТЕРФЕЙСА)

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

Как

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

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

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

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

Зачем

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

Иногда в ситуации, когда вам нужно выделить интерфейс, вы используете Crasrt Test Dummy (Тестирование обработки ошибок) или другой поддельный обь- екг (Mock Object). В этом случае подбор подходящего имени выполняется слож­нее, гак как и нашем распоряжении лишь один пример использования интерфейса. В подобных случаях у меня возникает соблазн наплевать на информативность и назвать ин герфейс Wte, а реализующий его класс - File. Однако я приучил себя останавливаться на мгновение и размышлять о том. достаточно ли хорошо я понимаю то. над чем работаю? Возможно, интерфейс лучше назвать File, а реа­лизующий его класс - OiskFikr, так как соответствующая реализация основана на том. что данные, содержащиеся в файле, хранятся на жестком диске.

MOVE METHOD (ПЕРЕМЕЩЕНИЕ МЕТОДА)

Каким образом метод можно переместить в hodoc место, где он должен находить­ся? Добавьте его в класс, к которому он должен принадлежать, затем обратитесь к нему.

Как

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

  2. Вставьте метод в целевой класс. Присвойте ему подобающее имя. Отхом лидируйте его.

  3. Если внутри метода происходит обращение к изначальному объекту, до­бавьте в метод параметр, при помощи которого внутрь метода будет пере­даваться изначальный объект. Если внутри метода происходит обращение к переменным*членам изначального объекта, передавайте их в виде пара метров. Если внутри метода перемен и ы м • членам изначального объекта присваиваются значения, вы должны отказаться от идеи переноса метода в новый объект.

  4. Замените тело изначального метода обращением к новому методу.

Зачем

Эго один из моих самых любимых рефакторингов, выполняемых в процессе кон­сультирования. Дело в том. что он наиболее эффективно демонстрирует испра­вил ьные предположения относительно дизайна кода.

Рефакторинг Move Method (Перемещение метода) обладает тремя важными преимуществами:

  • Очень легко увидеть необходимость применения этого рефакторинга. при этом не требуется глубокое понимание смысла кода. Как только вы уви­дите два иди больше сообщения, адресованных другому объекту, значит, можно смело приступать.

  • Механика выполнения рефакторинга быстра н безопасна.

  • Результаты зачастую приводят к просветлению. «Но масс Rectangle не вы­полняет никаких вычислений... О! Теперь я вижу. Так действительно луч­ше.»