Код, который рассказывает историю, или снова о чистоте кода

clean code

Эйнштейн однажды сказал:

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

Я совершенно уверен, что мистер Эйнштейн не написал при жизни ни строчки кода, однако, для таких людей, как я (а возможно и как вы), которые пишут и видят много кода, эти слова звучат так, как будто были написаны про разработчиков ПО.

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

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

Я знаю, что не решу проблему написанием очередной статьи, но я не могу промолчать! Я просто надеюсь, что кто-нибудь прочитает это, и исправится. Хотя бы на какое-то время. Хотя бы на день… Кто знает, возможно эта статья изменит хоть что-нибудь.

(далее…)

Создаем свой Фреймворк на компонентах Symfony2

Я совершенно не фанат Symfony2. У меня нет ни одного проекта на этом фреймворке, и вряд ли когда-нибудь хоть один появится. Это к тому, что я решил перевести цикл статей “Создаем свой Фреймворк на компонентах symfony2” совсем не из-за Symfony2. Этот цикл должен прочесть каждый. Этот цикл про программирование, про ООП, про архитектуру. Этот цикл — best practices разработки проектов на PHP. Изначально, конечно, Фабьен Потенсьер, автор оригинального текста и создатель Symfony2, задумывал эти статьи как рекламу своего фреймворка. Но что-то пошло не так…

Содержание цикла:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 12

В предыдущей статье цикла, мы убрали весь код из класса Framework, благодаря тому, что этот класс теперь наследуется от HttpKernel. И, раз уж, он пуст, возможно, вам захочется перенести сюда некоторый код из фронт-контроллера.

Сам фронт-контроллер стал куда более лаконичным:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 11

Если бы вы использовали наш фреймворк прямо сейчас, вы бы наверняка задумались о поддержке кастомных сообщений об ошибках. Мы уже имеем обработку для ошибок 404 и 500, но способ обработки захардкоден во фреймворке. Сделать их кастомизацию — легче легкого, достаточно определить новое событие, и слушателя, который будет вызывать по этому событию определенный контроллер. Вроде все просто, но, что если, в этом контроллере выбросить исключение? Вы получите бесконечный цикл! Не самый лучший вариант правда?

Посмотрим на класс HttpKernel, который является универсальной, расширенной и гибкой имплементацией интерфейса HttpKernelInterface. Этот класс очень похож на класс фреймворка, который мы пишем. Он управляет событиями в некоторых важных участках кода в процессе обработки запроса. Он использует Controller resolver, для сопоставления контроллера запросу. И в качестве бонуса, он предоставляет отличную обратную связь, при возникновении проблем.

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 10

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

HttpKernelInterface, наверное, самая важная часть кода в компоненте HttpKernel. Фреймворки и приложения реализующие этот интерфейс полностью совместимы. Более того, эта возможность может принести вам много отличного функционала.

Усовершенствуем фреймворк, для реализации данного интерфейса:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 9

У нас все еще отсутствует очень важное качество любого хорошего фреймворка: расширяемость. Расширяемость — значит, что любой программист может без проблем внедрить свой функционал в наш фреймворк и изменить способ обработки запроса.

О каком внедрении функционала я говорю? Например аутентификация, или кэширование инстансов. Причем внедрение функционала должно быть plug-and-play. По такому принципу работают например Drupal и WordPress. Часто эта возможность даже предусмотрена на уровне языка программирования, например WSGY в Python или Rack в Ruby.

Так как в PHP ничего подобного на уровне языка не предусмотрено, мы будем использовать хорошо известный шаблон Наблюдатель (Observer). В Symfony2 компонент EventDispatcher реализует упрощенную версию этого шаблона.

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 8

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

Сегодняшняя задача — написать юнит-тесты для нашего фреймворка, с помощью PHPUnit.

Создадим файл конфигурации для PHPUnit phpunit.xml.dist:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 7

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

Если присмотреться к front.php — можно увидеть, что мы принимаем данные запроса и выводим ответ. Наш класс будет придерживаться простого принципа: вся логика ограничена созданием ответа для запроса.

Так как, компоненты Symfony2 все равно требуют PHP 5.3, давайте для нашего класса определим пространство имен Simplex, и перенесем в него логику обработки запроса:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 6

Вы наверное думаете, что наш фреймворк уже достаточно хорош, и вы правы! Но, тем не менее, давайте посмотрим, как мы можем сделать его еще лучше.

Сейчас все наши примеры используют процедурный код, но помните, что контроллеры могут быть любыми валидными объектами типа PHP callbacks. Давайте представим наш контроллер в виде класса.

И, соответственно, обновим определение маршрута.

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 5

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

Давайте разделим код шаблонов и логику, добавив новый слой: Контроллер. Задача контроллера — генерировать ответ, основываясь на информации, переданной клиентским запросом.

Измените часть фреймворка, отвечающую за отображение шаблонов следующим образом:

(далее…)