Вы можете обнаружить, что после того, как вы изолировали изменение, а затем внесли это изменение в код, результат получился настолько тривиальным, что вы можете отменить изоляцию. Например, если мы обнаружили, что внутри метода findRate() должно присутствовать всего одно действие – возврат значения поля, мы можем вместо обращений к методу findRate() напрямую обратиться к полю. В результате метод findRate() можно будет удалить. Однако подобные изменения не следует выполнять автоматически. Постарайтесь найти баланс между затратами, связанными с использованием дополнительного метода, и пользой, которую приносит дополнительная концепция, добавленная в код.
Для изоляции изменений можно использовать несколько разных способов. Наиболее часто используется шаблон «Выделение метода» (Extract Method), помимо него также используются «Выделение объекта» (Extract Object) и «Метод в объект» (Method Object).
Как можно перейти от одного представления к другому? Временно дублируйте данные.
Как
Вначале рассмотрим версию «от внутреннего к внешнему». В рамках этого подхода вы изменяете вначале внутреннее представление, а затем внешний интерфейс.
1. Создайте переменную экземпляра в новом формате.
2. Инициализируйте переменную нового формата везде, где инициализируется переменная старого формата.
3. Используйте переменную нового формата везде, где используется переменная старого формата.
4. Удалите старый формат.
5. Измените внешний интерфейс так, чтобы использовать новый формат.
Однако в некоторых ситуациях удобнее сначала изменить API. В этом случае рефакторинг выполняется следующим образом.
1. Добавьте параметр в новом формате.
2. Обеспечьте преобразование параметра в новом формате во внутреннее представление, обладающее старым форматом.
3. Удалите параметр в старом формате.
4. Замените использование старого формата на использование нового формата.
5. Удалите старый формат.
Зачем
Проблема миграции данных возникает каждый раз, когда используется шаблон «От одного ко многим» (One to Many). Предположим, что мы хотим реализовать объект TestSuite, используя шаблон «От одного ко многим» (One to Many). Мы можем начать так:
def testSuite(self):
suite = TestSuite()
suite.add(WasRun("testMethod"))
suite.run(self.result)
assert("1 run, 0 failed" == self.result.summary())
Чтобы реализовать этот тест, начнем с одного элемента test:
class TestSuite:
def add(self, test):
self.test = test
def run(self, result):
self.test.run(result)
Теперь мы приступаем к дублированию данных. Вначале инициализируем коллекцию тестов:
TestSuite
def __init__(self):
self.tests = []
В каждом месте, где инициализируется поле test, добавляем новый тест в коллекцию:
TestSuite
def add(self, test):
self.test = test
self.tests.append(test)
Теперь мы используем коллекцию тестов вместо единичного теста. Исходя из существующего набора тестов данное преобразование можно считать рефакторингом (оно не нарушает семантику), так как в составе коллекции присутствует только один элемент.
TestSuite
def run(self, result):
for test in self.tests:
test.run(result)
Теперь можно удалить не используемую переменную экземпляра test:
TestSuite
def add(self, test):
self.tests.append(test)
Поэтапную миграцию данных можно использовать также при переходе между эквивалентными форматами, использующими различные протоколы, например, если речь идет о Java, при переходе от Vector/Enumerator к Collection/Iterator.
Как длинный сложный метод можно сделать простым для чтения? Выделите небольшую часть длинного метода в отдельный метод и обратитесь к этому методу из длинного метода.
Как
Выделение метода на самом деле является несколько более сложным атомарным рефакторингом. Здесь я опишу самый типичный случай. К счастью, многие среды разработки поддерживают автоматическое выполнение этого рефакторинга. Итак, чтобы выделить метод:
1. Определите фрагмент кода, который можно выделить в отдельный метод. Хорошими кандидатами являются тела циклов, сами циклы, а также ветви условных операторов.
2. Убедитесь, что внутри этого фрагмента не происходит присваивания значений временным переменным, объявленным вне области видимости, соответствующей этому фрагменту.
3. Скопируйте код из старого метода в новый. Скомпилируйте его.
4. Для каждой временной переменной или параметра первоначального метода, используемого в новом методе, добавьте параметр в новый метод.
5. Сделайте так, чтобы в нужном месте старый метод обращался к новому методу.
Зачем
Я использую «Выделение метода» (Extract Method), когда пытаюсь понять сложный код. «Значит так, этот кусок кода делает вот это. А этот кусок делает это. К чему мы там дальше обращаемся?» Через полчаса код будет выглядеть гораздо лучше, ваш партнер начнет понимать, что вы действительно оказываете ему помощь, а вы – существенно лучше понимать, что же все-таки происходит внутри кода.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии