Рефакторим легаси на PHP (с реальными примерами)

Хорошего программиста от плохо отличает «качество» его кода. В разработке, хороший код экономит деньги бизнесу, которые могли быть потрачены на тестирование, отладку, фикс багов и т.д. «плохого кода». В этой статье, я покажу реальные примеры некоторый идей и практик, которые помогут отрефакторить старый легаси, сделав его надежным и более модульным. Эти практики помогут не только с рефакторингом, но и с написанием «чистого кода».

Что такое рефакторинг и зачем он нужен?

Рефакторинг — это методы и шаги к тому, что бы сделать твой код более совершенным. Это важно для каждого разработчика, который хочет в итоге получить чистые, переиспользуемый и читаемый код. 

Ниже я покажу несколько примеров, как этого добиться.

Никогда не рефактори код, не покрытый тестами

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

Начинай рефакторинг из глубины кода

Посмотри на картинку ниже. Это реальный проект системы управления отелями, который я нашел на гитхабе.

На изображении видно три уровня вложенности, которые я отметил красным. Так вот начинать надо с третьего уровня вложенности, потому что чем глубже, тем более атомарная логика заложенная в куске кода, который понять и отрефакторить будет значительно проще. И постепенно поднимаясь вверх по коду, можно рефакторить более крупные куски кода. 

Делайте методы короче, разбивая их на более мелки методы

В данном коде мы можем выделить один приватный метод:

Следующим шагом будет выделение работы с  POST данными и вьюхами в отдельные методы:

Всегда используй скобки в условиях

Множество языков программирования позволяют использовать однострочные условия и некоторые разработчки используют это, однако, такой подход имеет ряд проблем. Во-первых, это становится нечитаемым, сложно глазами отделить это условие, от остального кода. Во-вторых, это порождает ошибки, когда необходимо в условие добавить ещё несколько строк кода, а скобки поставить забывают, в итоге в условие крашится. Посмотри на разницу:

Не используй магические цифры и строки

На следующем изображении видно, что если комнат больше чем 250, то мы показываем сообщение об ошибке. 250 — это магическое число, потому, что не понятно что это за число и почему именно 250, пока ты пишешь этот код и плюс минус пару недель ты помнишь, но затем ты уже забыл почему 250, или с твоим кода начал работать другой разработчик, который даже не представляет назначение этой цифры.

В процессе рефакторинга мы выясняем, что 250 — это максимальное количество комнат. Поэтому избавляемся от хардкода, и выделяем это числа в отдельную переменную $maxAvailableRooms. Теперь код стал более понятным и читаемым:

Не используй else конструкцию, если в этом нет необходимости

В этом же методе availablerooms(), мы можем легко избавиться от лишней вариативности, не изменив логику работы кода:

Используется говорящие имена переменных и методов

В примере ниже, ты можешь увидеть два метода с именами index и  room_m, лично я, не могу сказать что это за метода и что они делают. Поэтому лучше называть методы и переменные более описательно:

Используйте все возможности языка

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

В конце я хотел бы дать несколько советов по улучшению кода:

  • Используйте определение пустого массива через [], вместо старого array()
  • Старайтесь использовать тождественное сравнение  (===) вместо (==)
  • Public методам давай коротки описательные имена. Для private методов нормально использовать длинные имена, но по который будет ясен весь функционал данного метода
  • Удаляйте неиспользуемые методы
  • Используйте префиксы is и has для имен методов, которые возвращают булевы значения
  • Всегда используйте модификаторы доступа для методов и свойств
  • Public методы должны находиться вверху класса
  • Всегда используйте принцип единственной ответственности в классах

Вольный перевод Refactor Your PHP legacy Code (real projects examples)


Есть что написать?