Post on 08-May-2015
Работа с унаследованным кодом.Есть ли жизнь после коммита?
Вадим Крючков [Long]
Бюро Информационных Решений
Почему тема поднята именно сейчас?
Условия использования
• Внедрена любая CVS• Иметь (хотя бы поверхностные
представления) о тестировании
Вспомните — вы открываете код нового проекта и ...
Что такое "унаследованный код"?
• Не понятный код• Трудноизменяемый код• Код без тестов — без тестов мы не можем контролировать
изменение кода.
Чем он плох?
• До 70% рабочего времени мы читаем код• Требования меняются — код должен отвечать новым
требованиям• Мы не можем гарантировать:
– измененный код работает так, как предполагалось– изменения не поломали работающую систему
А изменения вносить надо!
Вариант альфа
Это не наш метод!
Откуда берется унаследованный код?
• Достается в «наследство»
• Мы сами его пишем
Почему код начинает загнивать?
Теория разбитых окон
• В 1982 году Джейм Уилсон и Джордж Келлинг
• Проверка — 6 экспериментов (подробнее — см. wikipedia.org)
Как бороться?
Основной метод — воспользоватьсяпринципом бойскаутов- покидая место, оставь его более чистым, чем оно было до твоего прихода
• Читаете код - если стало понятно что он делает — откомментируйте его
• Встретили метод без phpDoc - остановитесь, напишите его
• Если нужно внести изменение в метод - сначала напишите тест, который проверяет только этот метод, а потом вносите изменения
Главная проблема при коллективном владении кодом -
сделает кто-то другой
Код - это дом, в котором вам придется жить!
От теории к практике
• Общий подход • Несколько сложных случаев
Общий подход - условия
• Имеется унаследованный код• Необходимо в него внести изменения• Тестов нет. Ужас-ужас-ужас.
Общий подход - решение
Характеристические тесты — тесты, требующиеся для сохранения поведения системы
Особенности:• Пишутся по готовому работающему коду (anti-TDD)• Принцип белого ящика• Что делать с найденными ошибками? Сохранять поведение +
помечать на исправление.
Алгоритм построения характеристического теста
(1) Выбираем участок кода в методе (тестируем не весь метод!)(2) Пишем утверждение, которое заведомо противоречит этому
участку(3) Запускаем тест — тест провален(4) Изменяем тест — тест проходит(5) Возвращаемся к шагу (1)
Общий подход — правило применения
Прежде чем использовать любой метод — напишите на него характеристические тесты
Два характерных случая
Огромные методы
• Методы имеют тенденцию расти — в них вводят новую логику
• Метод начинает выполнять не одну, а много разных функций
Решение:• Реорганизация - извлечение метода• Извлекайте не большие, но логически
цельные фрагменты кода• Оставить только скелет — логику работы —
от изначального метода
Класс слишком крупный
• Принцип единственной ответственности — единственное назначение в системе, единственная причина для изменений
Извлечение класса:• Сгруппируйте сходные по именам методы — возможно они
группируются в отдельный класс• Анализ скрытых методов — наличие большого кол-ва приватных
и защищенных методов скорей всего означает, что требуется новый класс
• Существуют ли поля, которые используются в одних методах и не используются в других? Возможно их стоит объединить в отдельный класс?
Подробнее?
Мартин Фаулер. Рефакторинг. Улучшение существующего кода
Несколько советовиз практики
Распространение изменений
1. Возвращаемые значения — используются в вызывающей части2. Изменение объектов, передаваемых в параметрах3. Изменения данных, используемых в дальнейшем
Разбиение команд и запросов
• Командный метод — изменяет состояние объекта (данных)• Запросный метод — только возвращает значение
Метод должен быть либо командным, либо запросным, но не тем и не другим одновременно.
Запросный метод без проблем может быть использован повторно. Командный — можно получит не желательный эффект
Правка с единственной целью
• Часто изменяя один метод, возникает потребность исправить другой.
• Не поддавайтесь этому искушению. • Делайте все по порядку.• Запишите что хотели менять и вернитесь к первоначальной
задаче
Код (метод) слишком большой для понимания
• Распечатайте этот участок кода• Запаситесь маркерами• Если код глубоко вложенный — читайте его не опускаясь на
следующий уровень, после закрытой скобки поставьте комментарий. Повторите на новом уровне вложенности.
• Выделяйте группы ответственности одним цветом• Части кода, которые можно вынести в отдельный метод
обведите• Вернитесь в редактор и выполните изменения в коде
Код не понятен для его изменения
• Рисуйте эскизы — отмечайте связи между объектами• Совсем не обязательно использовать формальный UML — эскиз
нужен прежде всего вам!• Найдите на них объекты, на которые изменением будет оказано
воздействие
TDD и унаследованный код
Как использовать практику TDD?
Решение — разделите задачи:• Для нового кода — используйте TDD• Для унаследованного — пишите характеристические тесты
В результате — пишем новый код независимо от старого
Спасибо!
• l-o-n-g.livejournal.com• @v_kruchkov
Не пишите унаследованный код :)
Вопросы?