Переписать нельзя рефакторить

32
Переписать нельзя рефакторить! Пыхтин Павел Singularis Lab, Ltd. 28-29.10.2016 SECR'2016, Москва

Transcript of Переписать нельзя рефакторить

Page 1: Переписать нельзя рефакторить

Переписать нельзя рефакторить!

Пыхтин ПавелSingularis Lab, Ltd.

28-29.10.2016 SECR'2016, Москва

Page 2: Переписать нельзя рефакторить

228-29.10.2016 SECR'2016, Москва

Page 3: Переписать нельзя рефакторить

3

Legacy

• Уже работает в Production• Большое количество заплат• Устаревшие технологии• Неактуальная документация• Отсутствие единого стиля• …

28-29.10.2016 SECR'2016, Москва

Технический долг

Page 4: Переписать нельзя рефакторить

4

Выплачиваем долги

• Переписать с нуля+ Избавляемся от всех ошибок+ Получаем свободу в выборе

архитектуры и технологий– Долго– Несет заметные убытки для

бизнеса– «В этот раз уж точно

получится!»

28-29.10.2016 SECR'2016, Москва

Page 5: Переписать нельзя рефакторить

5

Выплачиваем долги

• Рефакторить модуль за модулем– Сложно– Приходится считаться с унаследованной

архитектурой (даже если ее нет)– Возможно окажется еще дольше+ Приложение продолжает развиваться+ Стоимость распределена по времени+ Есть возможность учесть новые требования

бизнеса

28-29.10.2016 SECR'2016, Москва

Page 6: Переписать нельзя рефакторить

6

Рефакторинг галазами заказчика

• «Мы сделали плохо, заплатите нам, чтобы мы все исправили»

• «Никаких изменений вы не заметите, но внутри будет намного лучше»

• «Я вчера прочитал, что наш фреймворк уже два месяца как устарел. Надо все переписать»

28-29.10.2016 SECR'2016, Москва

Page 7: Переписать нельзя рефакторить

7

Как убедить заказчика?

• У инженера и руководителя разные ценности• Ваши действия:

– Посмотрите на проблему с точки зрения бизнеса– Оцените текущие затраты на поддержку кода– Постарайтесь оценить эффект от рефакторинга– Составьте план работ с указанием требуемого времени и ожидаемых

результатов– Объясните причины, по которым возникли проблемы требующие

рефакторинга

28-29.10.2016 SECR'2016, Москва

Page 8: Переписать нельзя рефакторить

8

Вид работ Объем работ

Ожидаемый эффект Приоритет

Замена фронтенд фреймворка

160 Уменьшение времени загрузки страницы на 20%, упрощение поддержки и доработки

Высокий

Рефакторинг модуля импорта

80 Повышение надежности, уменьшение числа возникающих ошибок и, как следствие, повышение лояльности пользователей

Низкий

… … …

28-29.10.2016 SECR'2016, Москва

Page 9: Переписать нельзя рефакторить

9

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

• Мониторинг, логирование• Автоматизация процессов• Документация

28-29.10.2016 SECR'2016, Москва

Page 10: Переписать нельзя рефакторить

10

Мониторинг и логирование

• Упрощает решение имеющихся и новых проблем• Дает представление о текущем состоянии проекта• Обеспечивает быстрое оповещение о возникающих

проблемах• Можно использовать в качестве формального

показателя при оценке выгоды от рефакторинга

28-29.10.2016 SECR'2016, Москва

Page 11: Переписать нельзя рефакторить

11

Автоматизация процессов

• Сокращает издержки• Позволяет формализовать процессы• Позволяет выявить проблемные места в системе• Что автоматизировать:

– Сборку– Развертывание– Тестирование– …– Все, что занимает время, но не требует вашего полного внимания

28-29.10.2016 SECR'2016, Москва

Page 12: Переписать нельзя рефакторить

12

Документация

• Сбор и актуализация требований• Удаление избыточных требований• Написание сценариев тестирования

28-29.10.2016 SECR'2016, Москва

Page 13: Переписать нельзя рефакторить

13

Приступаем

• Всегда оставляйте после себя код чище, чем он был

• Вся команда должна быть вовлечена в процесс

• Используйте инструменты

28-29.10.2016 SECR'2016, Москва

Page 14: Переписать нельзя рефакторить

14

Статический анализ

• Позволяет отслеживать динамику состояния кода

• Позволяет выявлять проблемные места и цели для последующего рефакторинга

28-29.10.2016 SECR'2016, Москва

Page 15: Переписать нельзя рефакторить

15

Тесты

• Несколько тестов лучше, чем ничего• Тесты сами по себе являются документацией• Тесты помогут лучше спроектировать

архитектуру

28-29.10.2016 SECR'2016, Москва

Page 16: Переписать нельзя рефакторить

16

Практики• Extract Method• Inline Method• Inline Temp• Replace Temp with Query• Introduce Explaining Variable• Split Temporary Variable• Remove Assignments to Parameters• Replace Method with Method Object• Substitute Algorithm• Move Method• Move Field• Extract Class• Inline Class• Hide Delegate• Remove Middle Man• Introduce Foreign Method• Introduce Local Extension• Self Encapsulate Field• Replace Data Value with Object• Change Value to Reference• Change Reference to Value• Replace Array with Object• Duplicate Observed Data• Change Unidirectional Association to Bidirectional

• Change Bidirectional Association to Unidirectional• Replace Magic Number with Symbolic Constant• Encapsulate Field• Encapsulate Collection• Replace Record with Data Class• Replace Type Code with Class• Replace Type Code with Subclasses• Replace Type Code with State/Strategy• Replace Subclass with Fields• Decompose Conditional• Consolidate Conditional Expression• Consolidate Duplicate Conditional Fragments• Remove Control Flag• Replace Nested Conditional with Guard Clauses• Replace Conditional with Polymorphism• Introduce Null Object• Introduce Assertion• Rename Method• Add Parameter• Remove Parameter• Separate Query from Modifier• Parameterize Method• Replace Parameter with Explicit Methods• Preserve Whole Object

• Replace Parameter with Method• Introduce Parameter Object• Remove Setting Method• Hide Method• Replace Constructor with Factory Method• Encapsulate Downcast• Replace Error Code with Exception• Replace Exception with Test• Pull Up Field• Pull Up Method• Pull Up Constructor Body• Push Down Method• Push Down Field• Extract Subclass• Extract Superclass• Extract Interface• Collapse Hierarchy• Form Template Method• Replace Inheritance with Delegation• Replace Delegation with Inheritance• Tease Apart Inheritance• Convert Procedural Design to Objects• Separate Domain from Presentation• Extract Hierarchy

28-29.10.2016 SECR'2016, Москва

Page 17: Переписать нельзя рефакторить

17

Практики

• Выделение интерфейсов• Паттерн «Душитель»• Агрегация предыдущей реализации

28-29.10.2016 SECR'2016, Москва

Page 18: Переписать нельзя рефакторить

18

Выделение интерфейсов

• Цель:– Уменьшить связность классов

• Методика:– Группировка переменных и методов в соответствии со

сценариями использования– Инкапсуляция в отдельный класс– Перемещение ответственности за создание класса в контейнер

инъекции зависимостей

28-29.10.2016 SECR'2016, Москва

Page 19: Переписать нельзя рефакторить

19

Агрегация предыдущей реализации

• Цель:– Обеспечить возможность постепенного рефакторинга имеющейся реализации

• Методика:– Выделить интерфейс существующей реализации– Создать новую реализацию с тем же интерфейсом, агрегирующую

существующую в качестве скрытого поля– Пробросить вызовы в старую реализацию– Новые функции реализуются в новом сервисе– Старые функции рефакторятся и переносятся в новую реализацию по мере

возможности

28-29.10.2016 SECR'2016, Москва

Page 20: Переписать нельзя рефакторить

20

Паттерн «Душитель»

• Цель– Обеспечить возможность постепенного рефакторинга имеющейся

реализации• Методика:

– Создается новое приложение/сервис, которое впоследствии заменит существующее приложение

– Новые функции реализуются в новом приложении– Старые функции переносятся в новое приложение по мере

возможности

28-29.10.2016 SECR'2016, Москва

Page 21: Переписать нельзя рефакторить

21

To be continued…

28-29.10.2016 SECR'2016, Москва

Page 22: Переписать нельзя рефакторить

22

Наши инструменты

• ReSharper• Team City• Sonar Qube• BackstopJS• Eslint• Test link

28-29.10.2016 SECR'2016, Москва

Page 23: Переписать нельзя рефакторить

23

Байки

• Рефакторинг кода после 2-х лет разработки фрилансерами– Занял примерно полтора года– Средний размер класса сократился с 1000 строк до 200– Исправлено большое количество трудно

воспроизводимых ошибок– Функциональность системы была расширена вдвое

28-29.10.2016 SECR'2016, Москва

Page 24: Переписать нельзя рефакторить

24

Байки

• Переход с ADO.net на Nhibernate– Занял около полугода– Решены проблемы кэширования– Время старта приложения уменьшилось с 20

секунд до 7 секунд

28-29.10.2016 SECR'2016, Москва

Page 25: Переписать нельзя рефакторить

25

Байки

• Переход с jQuery + DevExpress на AngularJS– Около 15 000 строк JS кода– Выполнен на 50%– Трудозатраты на реализацию новой

функциональности сократились вдвое

28-29.10.2016 SECR'2016, Москва

Page 26: Переписать нельзя рефакторить

26

Памятка рефакторинга

• Определить масштаб проблем• Составить план рефакторинга (сроки, трудозатраты,

ожидаемый результат)• Настроить инструменты (логи, тесты, статический анализ…)• Донести до команды ценность рефакторинга и качественного

кода• …• Profit!

28-29.10.2016 SECR'2016, Москва

Page 27: Переписать нельзя рефакторить

2728-29.10.2016 SECR'2016, Москва

I HAVE A DREAM

THAT ONE DAY ALL LEGACY CODE WILL BE GONE

Page 28: Переписать нельзя рефакторить

28SECR'2016, Москва

Спасибо за внимание!Павел Пыхтин• [email protected]

https://www.singularis-lab.com/ https://www.linkedin.com/company/singularis-lab-llc http://habrahabr.ru/company/singularishttp://vk.com/singularis_lab

28-29.10.2016

Page 30: Переписать нельзя рефакторить

30

Технический долг

• Метафора, описывающая проблемы архитектуры или реализации.

• Не обязательно свидетельствует о низкой квалификации разработчика

• Стоит ли осознанно влезать в долги:– Это жизненно важно для проекта (прототип для демонстрации,

проверка гипотезы, hotfix…)– Поддержка текущей реализации не планируется (никем и никогда)

28-29.10.2016 SECR'2016, Москва

Page 31: Переписать нельзя рефакторить

31

Технический долг

• Компромисс между требованиями бизнеса и идеальным кодом

28-29.10.2016 SECR'2016, Москва

Качество

Требования

СрокиСтоимость

Page 32: Переписать нельзя рефакторить

32

Технический долг

• Компромисс между требованиями бизнеса и идеальным кодом

28-29.10.2016 SECR'2016, Москва

КачествоСтоимость Качество

Требования

Сроки