Рефакторинг который мы не делаем // PHP
Не так давно я описывал процесс рефакторинга одного проекта зашедшего в отдел, мы вместе посмеялись да поплакали, но ведать мораль оттуда не вынесли. И в этой истории мы не «белые и пушистые»…
История начиналась банально — проект загибается, заказчик ищет новую команду разработки и находит нас. Мы такие все из себя, на белом коне въезжаем в проект, а там ничего страшного, просто функциональный plain PHP код, т.е. классов нет, функций практически тоже (один файл functions.php, а в нем dbconnect(), userlogin() да функция-шаблонизатор, и что-то еще по мелочи). Смотрим — а проблема то в нагрузке — до 10 000 онлайн пользователей и в это время на сайт и зайти нельзя. Хорошо, задача ясна, садим в проект разработчика, который знаком с оптимизацией, ну и он начал работать. И да, после двух недель работы (а может и больше, уже не помню) сайт ожил, чуть-чуть индексов, чуть-чуть кеширования, еще немного оптимизации SQL запросов и нагрузка на сервера спала.
Заказчик доволен, и уже у него появляются «хотелки» на новый фичи, да немного еще старых багов подкидывает на фикс. В этот момент эффективность нашего разработчика сильно падает — он то любит заниматься оптимизацией, а вот эти CSS да JavaScript ну ой как туго идут…
Спустя некоторое время, мы заменяем разработчика в проекте, новому человеку больше по душе приходятся фичи и ченжи заказчика, и наша эффективность опять идет вверх, заказчик удовлетворен, мы считаем деньги. Все хорошо и ничто не предвещало случившегося.
В проекте всё меньше и меньше работы, задачи скатываются до уровня trivial, и мы принимаем решение посадить в него «зелёного» бойца, дабы опробовать его, да и заказчик дал на это добро. Старт был гладким, а потом начались проблемы, то вылезли за сроки, которые сами и оговорили, то на сервер залили не совсем рабочий код. И как итог — «Спасибо, что помогли, вы меня действительно выручили, но дальше я обойдусь без вас»
Начинаем разбор полётов, решаем, что новенького мы зря посадили в проект, но я к тому моменту залез в изучение кода по уши, и поэтому сейчас опишу то, чего я там не увидел.
Шаблонизатор
В системе был создан элементарный шаблонизатор с нативным синтаксисом (что скорее плюс), но в шаблонах постоянно встречались обращения к БД, и при изменении структуры приходилось перелапачивать не только код страниц, но и все шаблоны. Таким образом необходимо было разделить логику от представления раз и навсегда.
Если говорить о функции-шаблонизаторе, то вот элементарный пример:
/** * @param string * @param array */ function template($path, $vars = array()) { extract($vars); include $path; } template("templates/index.phtml", array( "foo" => "bar", "user" => $user ));
Остальное остается на совести разработчика, собственно даже в тот же Smarty можно впихнуть логику при должном желании.
Сущности
Процесс разработки так же затруднялся тем, что очень много копипаста было в проекте, и вносить изменения сразу и везде было проблематично (поиск и замена по папке это не тру). А необходимо было выделить сущности, и методы для работы с ними свести в один класс (или хотя бы файл). Таким образом мы бы смогли уменьшить повторение кода (и повторения ошибок).
Контроллеры
Тут просто напрашивался этот пункт, поэтому я его добавил, и хотел сказать следующее — если у вас в корне проекта лежит пару десятков файлов, то не стоит заморачиваться, и переписывать их все, чтобы у вас получилась папочка controllers и единая точка входа, ведь эти файлы с поставленной задачей вполне справляются. Как вывод — не стоит гнаться за идеальным кодом, такие вложения труда могут не окупиться.
Работа с БД
Как я описывал выше, SQL запросы встречались в проекте везде и всюду, и даже процесс экранирования входных данных в них был разный. Привести к единому стилю, создать нормальный врапер для БД, или хотя бы заменить использование расширения mysql на что-либо более современное.
Можно было бы написать простой врапер для врапера PDO за 20 минут, конечно он не будет универсален, но облегчит труд рефакторинга:
- легко логировать используя одну точку входа
- можно быстро добавить кеширование для всех запросов
Кеширование
Тут стоит упомянуть, кеширование прикрутили, НО лишь там где указал заказчик, а хотелось бы, чтобы был кеш везде где это имеет смысл, а не исходя из заключения «вроде тут», т.е. надо было в каждый файл заглянуть, логи проанализировать, да и время кеширования можно было потюнить в рейлтайме, но сдвиг часового пояса нам наверное сильно помешал, и никто не захотел ради этого из дома мониторить сервер, или хотя бы попросить об этом наших же админов (а мы такие услуги предоставляем ;).
Работа над ошибками
Тут все легко, если вы открываете PHP файл, а вам IDE подсказывает кричит о ошибках в коде, то уделите пять минут времени и исправьте их:
И еще — в обязательном порядке включите отображение ошибок, и запомните — «подавленный» Notice крадет время:
error_reporting(E_ALL); ini_set('display_errors', '1');
Тестирование
— Unit тестирование? О чем речь, у нас тут запара, надо выкатывать на лив!
Ну-ну…
Клиентская оптимизация
Этого пункта не коснулся ни один из разработчиков, участвовавших в проекте, и это действительно огорчает. Конечно, главная страничка проекта не слишком и тяжела — всего 300кб, но на них приходится 15 JS файлов, 18 картинок в CSS (спрайты спасут сервер), так же стоило потереть старые хуки для браузеров (IE5.5 и IE6), облегчить верстку, ведь 8,7kb это не так уж и мало (слишком много таблиц).
Собственно, сайт по оценке YSlow получает оценку C (70), что я считаю недопустимым, для сравнения мой блог с кучей картинок — A (90). Как улучшить эти показания очень хорошо рассказывает сайт webo.in, и я думаю ему стоит уделить место в закладках.
«Не наш» проект
Еще я бы хотел рассказать о том, что очень часто программисты не переживают и не живут проектом, а это очень негативно сказывается на взаимоотношения с заказчиком и на развитие проекта. Проект должен стать чем-то неотъемлемым от вас, если сайт загибается под наплывом пользователей — вам тоже должно быть не по себе, ведь это ваше творение страдает, и ему нужна ваша помощь. Вы как специалист должны советовать заказчику, как развивать проект, ведь именно вы знаете о всех ноу-хау в web-разработке, и не стоит ждать, что с предложением о улучшении выступит он, сделать первый шаг должны именно вы и именно сейчас. Не стоит в проекте жить одним днем, надо смотреть вперед и возможно рефакторинг проекта стоило начать еще вчера.
P.S
Если в вашем проект все идет гладко, то присмотритесь, возможно под столь сладким обликом притаился рак вашего безразличия к жизни проекта.
P.P.S
Если вы уже загорелись начать рефакторинг, то я вас еще чуть-чуть еще отвлеку — стоит рефакторинг правильно «продать» заказчику, который любит и умеет считать деньги, с ним стоит разговаривать именно в этом ключе. Удачи вам.