Избавляемся от дублирования кода:
внедрение аспектов в PHP с помощью библиотеки
                   Go! AOP

                  Alexander Lisachenko
                lisachenko.it@gmail.com
О докладчике




     Лисаченко Александр
• Архитектор веб-приложений в Alpari
• Идеолог Symfony2: почти десяток внутренних
сервисов на Symfony2, в т.ч. и основной сайт alpari.ru
(CDN,Varnish+ESI, Twig, Assetic, ~60 сабмодулей, ~20
бандлов)
Эволюция программирования




• Машинное программирование;
• Структурированное программирование;
• Процедурное программирование;
• Модульное программирование;
• Объектно-ориентированное программирование;
• < новая высокоуровневая парадигма >
Старое , доброе ООП …




Ключевые элементы: классы, объекты.
Принципы: абстрагирование, инкапсуляция,
наследование, полиморфизм.
Принцип единственной ответственности
Принцип единственной ответственности
Принцип единственной ответственности
Авторизация ...
Журналирование ...
Обработка ошибок ...
Почему же это так ?

Всему виной сквозная функциональность,
пронизывающая весь код, подобно шампуру.
Этот код не может быть вынесен в отдельные
классы и лежит везде:
• кэширование;
• журналирование;
• обработка исключений;
• проверка доступа;
• транзакционность.
Что у нас в итоге ?

Клинический диагноз типичного приложения:
<censored>-код:
• непригодный к повторному использованию;
• трудно понять исходное предназначение
класса, запутанная логика, большая
цикломатическая сложность;
• больше вероятность допустить ошибку, забыв
вписать «шаблонный» код;
• копирование кода обработки, нарушение
принципа DRY.
АОП нам в помощь !
АОП нам в помощь !

Аспектно-ориентированное программирование
                  (АОП)
• АОП - методика программирования в рамках
  классовой парадигмы, основанная на понятии
  аспекта — блока кода, инкапсулирующего
  сквозное поведение в составе классов.
История возникновения АОП

•1974 – принцип разделения ответственности
•1990е – исследования АОП
 • Composition Filters
 • Субъектно-ориентированное
   программирование
 • Адаптивное программирование
• 1997 - Аспектно-ориентированное
программирование (доклад на европейской
конференции по ООП)
• 2001 – разработка АОП фреймворка AspectJ
Основные понятия АОП



• Аспект (англ. aspect) — модуль или класс,
реализующий сквозную функциональность.
Аспект изменяет поведение остального кода,
применяя совет в точках соединения,
определённых некоторым срезом.
• Совет (англ. advice) — средство оформления
кода, который должен быть вызван из точки
соединения. Совет может быть выполнен до,
после или вместо точки соединения.
Основные понятия АОП



• Точка соединения (англ. join point) — точка в
выполняемой программе, где следует
применить совет.
• Срез (англ. pointcut) — набор точек
соединения. Срез определяет, подходит ли
данная точка соединения к данному совету.
• Внедрение (англ. introduction, введение) —
изменение структуры класса и/или изменение
иерархии наследования для добавления
функциональности аспекта в инородный код.
Основные понятия АОП
Базовые типы советов (Advice)




• Before - совет выполняется до вызываемого
метода или свойства.
• After - совет выполняется после вызываемого
метода.
• Around - совет выполняется вместо
вызываемого метода. Внутри обработчика есть
возможность ручной передачи управления в
вызываемый метод, если это необходимо.
Базовые типы советов (Advice)




                                       Before


                                        Before




                                After Throwing



                                         After
Место для АОП в PHP




 АОП органично дополняет существующие
технологии в единое целое:
• Внедрение зависимостей (IoC, DIC)
• Абстракция сервисов (yaml, xml, php)
• Аспектно-ориентированное программирование
Место для АОП в PHP




• Внедрение зависимостей
• Абстракция сервисов
• Аспектно-ориентированное программирование
Текущие реализации АОП в PHP

 Перспективные решения:
• AOP-PHP
• JMSAopBundle
• TYPO3 Flow AOP component
 Кладбище реализаций:
• PHPAspect
• Aspect-Oriented PHP
• AspectPHP
Библиотека Go!

  Базовая идея не нова — заменяем класс
аналогичной реализацией-декоратором.
  Ключевые моменты:
     • Статический анализ классов перед их
  загрузкой в память (php-token-reflection, ядро
  ApiGen)
     • Изменяем иерархию классов «на лету»
     • Модификация исходного кода класса в
  момент загрузки класса, кэшируем готовые
  классы
Библиотека Go!

• Не использует PHP-расширений, целиком
написана на самом PHP;
• Не требует DI-контейнера для подмены
сервисов прокси-объектами;
• Может перехватывать методы в финальных
классах, финальные методы, а также
статические методы;
• Может перехватывать обращения к
публичным и защищенным полям;
• Чистый генерируемый код, удобно проводить
отладку классов и аспектов с помощью XDebug
Исходный код класса
Класс аспекта
Результат выполнения
Обработанный код класса
Ловись рыбка большая ...
Ловись рыбка большая ...
Пример кэширования с аспектом
Что ожидается еще ?



• Парсер pointcut-ов (смотрим на FLOW3)
• Introduction — навешиваем трейты и
интерфейсы на классы
• Кэширование массива советов в shared-памяти
— не нужно проверять в рантайме вообще
ничего (привет, сериализация Closure)
• Поддержка точек init — отлаливаем все
конструкции new и выполняем свой код
• Максимальная производительность :)
Благодарю за внимание!
                    Вопросы?
Профиль нашей                  Ссылка на
компании на hh.ru              библиотеку

Внедрение аспектов в PHP с помощью библиотеки GO! AOP

  • 1.
    Избавляемся от дублированиякода: внедрение аспектов в PHP с помощью библиотеки Go! AOP Alexander Lisachenko lisachenko.it@gmail.com
  • 2.
    О докладчике Лисаченко Александр • Архитектор веб-приложений в Alpari • Идеолог Symfony2: почти десяток внутренних сервисов на Symfony2, в т.ч. и основной сайт alpari.ru (CDN,Varnish+ESI, Twig, Assetic, ~60 сабмодулей, ~20 бандлов)
  • 3.
    Эволюция программирования • Машинноепрограммирование; • Структурированное программирование; • Процедурное программирование; • Модульное программирование; • Объектно-ориентированное программирование; • < новая высокоуровневая парадигма >
  • 4.
    Старое , доброеООП … Ключевые элементы: классы, объекты. Принципы: абстрагирование, инкапсуляция, наследование, полиморфизм.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
    Почему же этотак ? Всему виной сквозная функциональность, пронизывающая весь код, подобно шампуру. Этот код не может быть вынесен в отдельные классы и лежит везде: • кэширование; • журналирование; • обработка исключений; • проверка доступа; • транзакционность.
  • 12.
    Что у насв итоге ? Клинический диагноз типичного приложения: <censored>-код: • непригодный к повторному использованию; • трудно понять исходное предназначение класса, запутанная логика, большая цикломатическая сложность; • больше вероятность допустить ошибку, забыв вписать «шаблонный» код; • копирование кода обработки, нарушение принципа DRY.
  • 13.
    АОП нам впомощь !
  • 14.
    АОП нам впомощь ! Аспектно-ориентированное программирование (АОП) • АОП - методика программирования в рамках классовой парадигмы, основанная на понятии аспекта — блока кода, инкапсулирующего сквозное поведение в составе классов.
  • 15.
    История возникновения АОП •1974– принцип разделения ответственности •1990е – исследования АОП • Composition Filters • Субъектно-ориентированное программирование • Адаптивное программирование • 1997 - Аспектно-ориентированное программирование (доклад на европейской конференции по ООП) • 2001 – разработка АОП фреймворка AspectJ
  • 16.
    Основные понятия АОП •Аспект (англ. aspect) — модуль или класс, реализующий сквозную функциональность. Аспект изменяет поведение остального кода, применяя совет в точках соединения, определённых некоторым срезом. • Совет (англ. advice) — средство оформления кода, который должен быть вызван из точки соединения. Совет может быть выполнен до, после или вместо точки соединения.
  • 17.
    Основные понятия АОП •Точка соединения (англ. join point) — точка в выполняемой программе, где следует применить совет. • Срез (англ. pointcut) — набор точек соединения. Срез определяет, подходит ли данная точка соединения к данному совету. • Внедрение (англ. introduction, введение) — изменение структуры класса и/или изменение иерархии наследования для добавления функциональности аспекта в инородный код.
  • 18.
  • 19.
    Базовые типы советов(Advice) • Before - совет выполняется до вызываемого метода или свойства. • After - совет выполняется после вызываемого метода. • Around - совет выполняется вместо вызываемого метода. Внутри обработчика есть возможность ручной передачи управления в вызываемый метод, если это необходимо.
  • 20.
    Базовые типы советов(Advice) Before Before After Throwing After
  • 21.
    Место для АОПв PHP АОП органично дополняет существующие технологии в единое целое: • Внедрение зависимостей (IoC, DIC) • Абстракция сервисов (yaml, xml, php) • Аспектно-ориентированное программирование
  • 22.
    Место для АОПв PHP • Внедрение зависимостей • Абстракция сервисов • Аспектно-ориентированное программирование
  • 23.
    Текущие реализации АОПв PHP Перспективные решения: • AOP-PHP • JMSAopBundle • TYPO3 Flow AOP component Кладбище реализаций: • PHPAspect • Aspect-Oriented PHP • AspectPHP
  • 24.
    Библиотека Go! Базовая идея не нова — заменяем класс аналогичной реализацией-декоратором. Ключевые моменты: • Статический анализ классов перед их загрузкой в память (php-token-reflection, ядро ApiGen) • Изменяем иерархию классов «на лету» • Модификация исходного кода класса в момент загрузки класса, кэшируем готовые классы
  • 25.
    Библиотека Go! • Неиспользует PHP-расширений, целиком написана на самом PHP; • Не требует DI-контейнера для подмены сервисов прокси-объектами; • Может перехватывать методы в финальных классах, финальные методы, а также статические методы; • Может перехватывать обращения к публичным и защищенным полям; • Чистый генерируемый код, удобно проводить отладку классов и аспектов с помощью XDebug
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
    Что ожидается еще? • Парсер pointcut-ов (смотрим на FLOW3) • Introduction — навешиваем трейты и интерфейсы на классы • Кэширование массива советов в shared-памяти — не нужно проверять в рантайме вообще ничего (привет, сериализация Closure) • Поддержка точек init — отлаливаем все конструкции new и выполняем свой код • Максимальная производительность :)
  • 34.
    Благодарю за внимание! Вопросы? Профиль нашей Ссылка на компании на hh.ru библиотеку