Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Аспектно-ориентированное программирование в PHP

Аспектно-ориентированное программирование в PHP

Alexander Lisachenko

June 14, 2013
Tweet

More Decks by Alexander Lisachenko

Other Decks in Programming

Transcript

  1. О докладчике Лисаченко Александр • Архитектор веб-приложений в Alpari •

    Опыт работы во всех основных направлениях PHP-разработки (highload, бизнес- приложения, веб-сервисы, соц. сети) • Идеолог Symfony2: почти десяток внутренних сервисов на Symfony2, в т.ч. и основной сайт alpari.ru (CDN, Varnish+ESI, Twig, Assetic, ~60 сабмодулей, ~20 бандлов) Twitter: @lisachenko Github: https://github.com/lisachenko
  2. Почему это плохо? Плюсы: • Видна вся логика метода Минусы:

    • Код нельзя использовать повторно • трудно понять исходное предназначение класса • запутанная логика • больше вероятность допустить ошибку, забыв вписать «шаблонный» код • нарушение принципа DRY
  3. Аспектно-ориентированное программирование АОП - методика программирования в рамках классовой парадигмы,

    основанная на понятии аспекта — блока кода, инкапсулирующего сквозное поведение в составе классов.
  4. Аспектно-ориентированное программирование Методология АОП была предложена группой инженеров исследовательского центра

    Xerox PARC под руководством Грегора Кичалеса (Gregor Kiczales). Ими же было разработано аспектно- ориентированное расширение для языка Java, получившее название AspectJ — (2001 год).
  5. Аспектно-ориентированное программирование АОП дает возможность вызвать дополнительный код (хук) в

    определенный момент работы программы: до выполнения метода, после выполнения метода, при обращении к свойству и другим без изменения исходного кода программы!
  6. Ключевые понятия и термины Aspect • Модуль или класс, реализующий

    сквозную функциональность. • Аспект изменяет поведение остального кода, применяя совет в точках соединения, определённых некоторым срезом Advice (совет) • Дополнительная логика, которая должна быть вызвана из точки соединения
  7. Ключевые понятия и термины Joinpoint • Точка в выполняемой программе,

    где следует применить совет • Выполнение метода, обращение к свойствам объекта и др. Pointcut (срез) • Набор точек соединения. • Срез определяет, подходит ли данная точка соединения к данному совету
  8. Процесс вплетения кода Перехват include/require Stream wrapper (php://filter) Статический анализ

    кода (token_get_all) TokenReflection Анализ Pointcut-ов Модификация исходного кода
  9. Фреймворк Go! AOP PHP • Не использует PHP-расширений, целиком написан

    на самом PHP; • Может быть использован с любым приложением на PHP; • Оптимизирован (ленивая загрузка ядра, кэширование классов, поддержка опкод-кэшеров) • Не требует DI-контейнера для подмены сервисов прокси- объектами; • Может перехватывать динамические и статические методы, методы в финальных классах, а также методы в трейтах; • Может перехватывать обращения к публичным и защищенным полям; • Чистый генерируемый код, удобно проводить отладку классов и аспектов с помощью XDebug
  10. Срезы точек в Go! AOP PHP 1. Выполнение методов 1.

    Динамических: execution(public Example->method(*)) 2. Статических: execution(public **::*someStatic*Method*(*)) 3. Защищенных: execution(protected Ns\**\Example->protected*(*)) 4. С аннотацией: @annotation(First\Second\Annotation\Class) 2. Все методы в определенном классе 1. Конкретный класс: : within(Go\Aspects\Test) 2. В указанном неймспейсе: within(Go\Aspects\*) 3. Включая суб-неймспейсы: within(Go\Aspects\**) 4. Потомки конкретного класса: within(DemoInterface+) 3. Обращение к свойствам 1. Публичные: access(* Example\Aspect\*->property*) 2. Защищенные: access(protected Test\Class*->protected*Property) 4. Логические 1. ИЛИ : within(A) || within(B) 2. И: within(A) && within(B) 3. НЕ: !within(A)
  11. Пример: trait + interface + AOP = Introduction Introduction •

    возможность динамически подключать интерфейсы и типажи к конкретному классу.
  12. Пример: trait + interface + AOP = Introduction Исходный класс

    •Обратите внимание, что мы не имплементриуем интерфейсов и не подключаем типажи в исходном классе.
  13. Пример: trait + interface + AOP = Introduction Класс после

    вплетения кода •К классу был добавлен динамически заданный интерфейс и типаж
  14. За и против глобальных срезов За •Позволяет сделать срез в

    любом коде, даже стороннем •Легко описать нужный неймспейс •Быстрота внедрения •Не нужно менять исходный код вообще Против •Action at a distance – непредсказуемые эффекты в коде методов •Цепляет и нужное и ненужное •Может немного замедлить приложение из-за большого количества точек •Высока вероятность допустить ошибку
  15. Контроллируемые срезы За •Используются стандартная технология интерфейсов- маркеров и срез

    within(InterfaceName+) •Используются наглядные аннотации-маркеры перед методами и срез @annotation(ClassName) •Влияют только на указанный разработчиком код (ожидаемое поведение) Против •Необходимо вносить небольшие правки в исходный код •Ограниченная возможность работать с сторонним кодом
  16. Проблема с доступом к состоянию объекта 1. Как вы уже

    наверное поняли, основное достоинство настоящего АОП – это возможность дополнять логику методов или целого класса дополнительным функционалом без изменения исходного кода. 2. Но класс аспекта является внешним по отношению к классу перехватываемого объекта, а значит, мы можем пользоваться только публичными данными объекта, а что делать если нужно обратиться к приватным или защищенным полям или методам объекта?
  17. Привилегированные советы Привилеги- рованный совет • Совет (метод) в классе

    аспекта, который выполняется в области видимости текущего объекта и имеет доступ к приватным и защищенным полям и методам класса
  18. АОП – следующий шаг в развитии PHP ООП Абстракция сервисов

    (yaml, xml, php) Внедрение зависи- мостей (IoC, DIC) Аспектно- ориентиро- ванное программи- рование
  19. AOP: за и против За •Управление сквозной функциональностью •Снижение стоимости

    разработки •Более прозрачный код логики •Уменьшение шаблонных ошибок •Уменьшение связанности классов •Повторное использование кода Против •Порог вхождения •Неявные эффекты •Ограниченная помощь IDE •Незначительное снижение скорости выполнения кода