xp days ukraine 2014 - refactoring legacy code

43
Refactoring Legacy Code Дмитрий Миндра SDET, Unity Technologies (Ciklum) @dmytromindra

Upload: dmytro-mindra

Post on 16-Jul-2015

486 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: XP Days Ukraine 2014 - Refactoring legacy code

Refactoring Legacy Code

Дмитрий Миндра

SDET, Unity Technologies (Ciklum)

@dmytromindra

Page 2: XP Days Ukraine 2014 - Refactoring legacy code

О докладчике

2010 - Lohika

2012 - Microsoft

2013 - Unity Technologies

Когда-то был приличным

инженером, но 10 лет назад

связался с дотнетчиками,

выучил C#, занялся ООП,

скатился к TDD и

модульному тестированию.

Характер скверный.

Женат

Page 3: XP Days Ukraine 2014 - Refactoring legacy code

Extreme Programming (XP)

Page 4: XP Days Ukraine 2014 - Refactoring legacy code
Page 5: XP Days Ukraine 2014 - Refactoring legacy code

SCRUM ЭРА

Page 6: XP Days Ukraine 2014 - Refactoring legacy code

Что такое legacy code?

1. Это код без тестов

2. Код без спецификации

3. Код написанный очень давно и

неизвестно кем.

4. …

MakeFlagWavingBastardWaveHisFlagWhichIsTheProbablyTheLastThingHeWillEverDo()

Найдено в Carmageddon 1 debugging symbols dumped

Page 7: XP Days Ukraine 2014 - Refactoring legacy code
Page 8: XP Days Ukraine 2014 - Refactoring legacy code

Как появляется Legacy Code?

Page 9: XP Days Ukraine 2014 - Refactoring legacy code

Как появляется legacy code?

• Гонка за фичами (нужно больше золота)

• Меняющиеся требования.

• Костыли и хаки.

• Ротация разработчиков.

• Отсутствие мыслей о завтрашнем дне (

сопровождении кода )

Page 10: XP Days Ukraine 2014 - Refactoring legacy code

Золотое правило

• Работает – не трогай!

Page 11: XP Days Ukraine 2014 - Refactoring legacy code

Зачем мы меняем код ?

• Нужно добавить фичу.

• Нужно пофиксить баг.

• Нужно улучшить производительность.

Page 12: XP Days Ukraine 2014 - Refactoring legacy code

ВАЖНО!

• Legacy код – это всегда работающий

код, задействованный в

функционировании программной

системы.

Page 13: XP Days Ukraine 2014 - Refactoring legacy code

Что делать?

• Переписать заново (как правило плохая

мысль)

• Найти новую работу …

• Сделать код «не legacy» кодом.

Page 14: XP Days Ukraine 2014 - Refactoring legacy code

Учись, иначе т

Учись, студент! Иначе, всю

жизнь вот так будешь

только ключи подавать!

Page 15: XP Days Ukraine 2014 - Refactoring legacy code

Самая популярная техника

работы с Legacy Code

Edit and pray

Page 16: XP Days Ukraine 2014 - Refactoring legacy code

С чего начать ?

• Определить что именно нужно менять

• Определить какие тесты нужны

• Запустить и проверить

• Написать тесты

• Внести изменения

Page 17: XP Days Ukraine 2014 - Refactoring legacy code

С чего начать ?

• Определить что именно нужно менять

– Старый код бывает очень сложно понять

– Изменения могут быть сильно

распределены по коду

• Определить какие тесты нужны

• Запустить и проверить

• Написать тесты

• Внести изменения

Page 18: XP Days Ukraine 2014 - Refactoring legacy code
Page 19: XP Days Ukraine 2014 - Refactoring legacy code

С чего начать ?

• Определить что именно нужно менять

• Определить какие тесты нужны– Мы хотим убедиться, что код работает так же,

как работал до вмешательства.

– Есть ли механизм для мониторинга результатов.

– Мы не боимся долгих и сложных тестов на этом этапе!

• Запустить и проверить

• Написать тесты

• Внести изменения

Page 20: XP Days Ukraine 2014 - Refactoring legacy code

Approval Tests

1. Сериализуем результат в текст

2. Сравниваем с эталоном

http://approvaltests.sourceforge.net

Page 21: XP Days Ukraine 2014 - Refactoring legacy code

С чего начать ?

• Определить что именно нужно менять

• Определить какие тесты нужны

• Запустить и проверить

– Можем ли мы создать класс/вызвать метод в тесте?

– Можем ли мы получить результат вычислений?

• Написать тесты

• Внести изменения

Page 22: XP Days Ukraine 2014 - Refactoring legacy code

Seams

• Швы – места, позволяющие менять

поведение программы не меняя код в

этом самом месте.

• Швы бывают объектные и линковочные

Page 23: XP Days Ukraine 2014 - Refactoring legacy code

Sensing and Separation

• Sensing – мы меняем код для того,

чтобы получить доступ к результатам

вычислений.

• Separation – мы меняем код для того,

чтобы получить создать класс или

вызвать метод внутри теста.

Page 24: XP Days Ukraine 2014 - Refactoring legacy code

Separation

В данном случае мы будем бороться за право создать экземпляр.

Самый простой рефакторинг – это добавить конструктор по умолчанию.

Page 25: XP Days Ukraine 2014 - Refactoring legacy code

Separation

Старый код часто нарушает принцип DI

Page 26: XP Days Ukraine 2014 - Refactoring legacy code
Page 27: XP Days Ukraine 2014 - Refactoring legacy code

Избавляемся от зависимости

• Пожалуй самая распространенная

техника – Extract Interface &

Parameterize Constructor.

Page 28: XP Days Ukraine 2014 - Refactoring legacy code

Extract Interface

Сначала избавимся от очень общего названия Sensor

Затем извлечем интерфейс Sensor

Page 29: XP Days Ukraine 2014 - Refactoring legacy code

Parameterize Constructor

Конструктор по умолчанию все еще создает зависимость,

но теперь есть возможность подменить ее в тесте.

Page 30: XP Days Ukraine 2014 - Refactoring legacy code

Extract and Override (шаг 1)

Было:

Стало:

Factory Method

Page 31: XP Days Ukraine 2014 - Refactoring legacy code

Extract and Override (шаг 2)Factory Method

Page 32: XP Days Ukraine 2014 - Refactoring legacy code

Почему Extract and Override?

• Legacy code – это зона риска. Мы

стараемся менять его минимальными

безопасными шагами (baby steps).

Page 33: XP Days Ukraine 2014 - Refactoring legacy code

Шаг 1: Добавить метод

Page 34: XP Days Ukraine 2014 - Refactoring legacy code

Шаг 1: Добавить методПопробуем обернуть вызов source.Read() методом Modify()

Это безопасная операция с минимальной модификацией

кода.

Page 35: XP Days Ukraine 2014 - Refactoring legacy code

Шаг 2: Перегрузить его

Безопасно ли поменять private на protected? Вполне!

Безопасно ли сделать метод virtual? Вполне!

Page 36: XP Days Ukraine 2014 - Refactoring legacy code

Теперь мы можем переопределить это поведение в

наследнике операцией, не меняющей исходный код

тестируемого класса.

Шаг 2: Перегрузить его

Page 37: XP Days Ukraine 2014 - Refactoring legacy code

Extract and Override3rd party

Ох уж эти 3rd party, которые так сложно тестировать.

Extract

Override

Page 38: XP Days Ukraine 2014 - Refactoring legacy code

Sensing with Extract and Override

Page 39: XP Days Ukraine 2014 - Refactoring legacy code

С чего начать ?

• Определить что именно нужно менять

• Определить какие тесты нужны

• Запустить и проверить

• Написать тесты

– Эти тесты больше похожи на приемочные тесты.

– Они могут быть медленными, могут обращаться к внешним сервисам и базам данных

– Главная цель этих тестов определить работает ли старый код так же, как работал до вмешательства.

• Внести изменения

Page 40: XP Days Ukraine 2014 - Refactoring legacy code

С чего начать ?

• Определить что именно нужно менять

• Определить какие тесты нужны

• Запустить и проверить

• Написать тесты

• Внести изменения и выполнить настоящий рефакторинг

– Когда код покрыт тестами он уже формально не является легаси кодом.

– Его можно рефакторить и править.

Page 41: XP Days Ukraine 2014 - Refactoring legacy code

Вопросы

?

Page 42: XP Days Ukraine 2014 - Refactoring legacy code

Что почитать?

Michael C. Feathers “Working Effectively

With Legacy Code”

Page 43: XP Days Ukraine 2014 - Refactoring legacy code

Упражнение

https://github.com/DmytroMindra/GildedRos

e