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

32. Понятие рефакторинга. Рефакторинги «Согласование различий», «Миграция данных», «Выделение метода».

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

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

RECONCILE DIFFERENCES (СОГЛАСОВАНИЕ РАЗЛИЧИЙ)

Каким образом пм можете унифицировать два схожих фрагмента кода? Посте­пенно делайте их все более похожими друг на друга. Унифицируйте их только в случае, если они абсолютно идентичны.

Подчас выполнение рефакторнига — это весьма нервная работа. Простые ре- факторинг)! очевидны. Если я извлекаю метод и делаю это механически корректно, вероятность того, что поведение системы изменится, чрезвычайно мала. Однако некоторые из рсфакторимгов заставляют вас внимательно анализировать после­довательность выполнения операций и порядок модификации данных. Построив длинную цепочку умозаключений, вы приходите к выводу, что запланированное вами изменение кода, скорое всего, не приведет к изменению поведения системы. Однако любой подобный рефакторинг уменьшает количество волос на вашей го­лове

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

Подобные рефакторинги возникают на разных уровнях:

  • Два цикла выглядят похоже. Если вы сделаете их идентичными, вы можете объединить их в единый цикл.

  • Две ветви условного оператора выглядят похоже. Сделав их идентичными, вы можете избавиться от условного оператора.

  • Два метода выглядят похоже. Сделав их идентичными, вы можете изба­виться от одного из них.

  • Два класса выглядят похоже. Сделав их идентичными, вы можете изба­виться от одного из них.

Иногда задачу согласования различий удобнее решать в обратном порядке. Иными словами, вы представляете себе самый тривиальный последний этап этой процедуры, а затем двигаетесь в обратном направлении. Например, если вы хотите избавиться от нескольких подклассов, наиболее тривиальный последний шаг можно будет выполнить в случае, если подкласс ничего не содержи i В этом слу­чае везде, где используется подкласс, можно будет использовать суперкласс, при этом поведение системы не изменится. Что надо сделать, чтобы очистить под­класс от методов и данных? Для начала метод можно сделать полностью иден­тичным одному из методов суперкласса. Постепенно переместив все методы и все данные в суперкласс, вы сможете .заменить ссылки на подкласс ссылками на су­перкласс. После этого подкласс можно уничтожить.

MIGRATE DATA (МИГРАЦИЯ ДАННЫХ)

Каким образом можно перейти от одного представления к другому? Временно дублируйте данные.

Как

Вначале рассмотрим версию «от внутреннего к внешнему». В рамках этого под­хода вы вначале изменяете внутреннее представление, а затем меняете внешний

интерфейс.

  1. Создайте экземплярную переменную в новом формате.

  2. Инициализируйте переменную нового формата везде, где инициализиру­ется переменная старого формата.

  3. Используйте переменную нового формата везде, где используется пере­менная старого формата.

  4. Удалите старый формат.

  5. Измените внешний интерфейс таким образом, чтобы использовать новый формат.

Однако в некоторых ситуациях вам удобнее вначале изменить API. В этом случае вы должны выполнить рефакторинг следующим образом:

  1. Добавьте параметр в новом формате

  2. Обеспечьте преобразование параметра в новом формате во внутреннее представление, обладающее старым форматом.

  3. Удалите параметр в старом формате.

  4. Замените использование старого формата на использование нового формата.

  5. Удалите старый формат.

EXTRACT METHOD (ВЫДЕЛЕНИЕ МЕТОДА)

Каким образом длинный сложный метод можно сделать простым в прочтении? Выделите небольшую часть длинного метода в отдельный метод и обратитесь к этому методу из длинного метода.

Как

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

  1. Определите фрагмент кода, который можно выделить в отдельный метод. Хорошими кандидатами являются тела циклов, сами циклы, а также ветви условных опера юрой.

  2. Убедитесь в том, что внутри эгого фрагмента не происходит присвоения значений временным переменным, обьявленмым вне области видимости, соответствующей этому фрагменту.

  3. Скопируйте код из старою метода в новый метод. Откомпилируйте его.

  4. Для каждой временной переменной или параметра изначального метода, используемого в новом методе, добавьте параметр в новый метод,

  5. Сделайте так, чтобы в нужном месте старый метод обращался к новому ме­тоду.

Зачем

Я использую Extract Method (Выделение .метода), когда пытаюсь понять сложный код. «Значит так, этот кусок кода делает вот это. А этот кусок делает это. К чему мы там дальше обращаемся?* После получаса код выглядит гораздо лучше, ваш партер начинает понимать, что вы действительно оказываете ему помощь» а вы существенно лучше понимаете, что же все-таки происходи! внутри кода.

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

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