$30 off During Our Annual Pro Sale. View Details »

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

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

Alexander Lisachenko

June 14, 2013
Tweet

More Decks by Alexander Lisachenko

Other Decks in Programming

Transcript

  1. Аспектно-ориентированное
    программирование в PHP
    Лисаченко Александр, архитектор web-приложений Alpari-RU

    View Slide

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

    View Slide

  3. Эволюция технологий
    Машинное программирование
    Структурированное программирование
    Процедурное программирование
    Модульное программирование
    Объектно-ориентированное программирование
    ???

    View Slide

  4. Логические единицы кода
    • Функции
    • Процедуры
    Процедурное
    • Модули
    Модульное
    • Классы
    • Методы
    • Свойства
    ООП

    View Slide

  5. Принцип единственной отвественности

    View Slide

  6. Принцип единственной отвественности

    View Slide

  7. Сквозная функциональность

    View Slide

  8. Сквозная функциональность
    Сквозная
    функцио-
    нальность
    Авторизация
    Обработка ошибок
    Кэширование
    Ведение логов

    View Slide

  9. Управление авторизацией

    View Slide

  10. Журналирование

    View Slide

  11. Обработка ошибок

    View Slide

  12. Матрешка функциональности
    Авто-
    ризация
    Логиро-
    вание
    Обра-
    ботка
    ошибок
    Основ-
    ной код

    View Slide

  13. Почему это плохо?
    Плюсы:
    • Видна вся логика метода
    Минусы:
    • Код нельзя использовать
    повторно
    • трудно понять исходное
    предназначение класса
    • запутанная логика
    • больше вероятность
    допустить ошибку, забыв
    вписать «шаблонный»
    код
    • нарушение принципа DRY

    View Slide

  14. Аспектное программирование
    Процедурное
    программирование
    ООП
    АОП

    View Slide

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

    View Slide

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

    View Slide

  17. Аспектно-ориентированное программирование
    АОП дает возможность
    вызвать дополнительный код
    (хук) в определенный
    момент работы программы:
    до выполнения метода,
    после выполнения метода,
    при обращении к свойству и
    другим без изменения
    исходного кода программы!

    View Slide

  18. Ключевые понятия и термины
    Аspect-
    Oriented
    Program-
    ming
    Joinpoint
    Pointcut
    Advice
    Aspect
    Introduction

    View Slide

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

    View Slide

  20. Ключевые понятия и термины
    Joinpoint
    • Точка в выполняемой
    программе, где следует
    применить совет
    • Выполнение метода,
    обращение к свойствам
    объекта и др.
    Pointcut
    (срез)
    • Набор точек соединения.
    • Срез определяет, подходит
    ли данная точка соединения
    к данному совету

    View Slide

  21. Пример: паттерн FluentInterface
    Method execution joinpoint
    Property access joinpoint

    View Slide

  22. Пример: паттерн FluentInterface
    Advice
    Pointcut
    definition
    Aspect class

    View Slide

  23. Процесс вплетения кода
    Перехват
    include/require
    Stream wrapper
    (php://filter)
    Статический
    анализ кода
    (token_get_all)
    TokenReflection
    Анализ
    Pointcut-ов
    Модификация
    исходного кода

    View Slide

  24. Пример: паттерн Fluent Interface
    Around advice
    Original method
    Original
    method
    AOP

    View Slide

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

    View Slide

  26. Срезы точек в 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)

    View Slide

  27. Типажи (trait) в PHP – хорошо или плохо?
    Хорошо Плохо

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  31. Пример: логирование на уровне приложения

    View Slide

  32. View Slide

  33. Пример: логирование на уровне приложения

    View Slide

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

    View Slide

  35. View Slide

  36. View Slide

  37. Пример: логирование на уровне приложения

    View Slide

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

    View Slide

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

    View Slide

  40. Привилегированные советы
    Привилеги-
    рованный
    совет
    • Совет (метод) в классе аспекта,
    который выполняется в области
    видимости текущего объекта и
    имеет доступ к приватным и
    защищенным полям и методам
    класса

    View Slide

  41. Попробуем считать поле $name в совете

    View Slide

  42. Обычный совет работает согласно scope

    View Slide

  43. Привилегированный совет

    View Slide

  44. Привилегированный совет в scope объекта

    View Slide

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

    View Slide

  46. AOP: за и против
    За
    •Управление сквозной
    функциональностью
    •Снижение стоимости
    разработки
    •Более прозрачный код логики
    •Уменьшение шаблонных ошибок
    •Уменьшение связанности
    классов
    •Повторное использование кода
    Против
    •Порог вхождения
    •Неявные эффекты
    •Ограниченная помощь IDE
    •Незначительное снижение
    скорости выполнения кода

    View Slide

  47. Благодарю за внимание!
    Go! AOP PHP: https://github.com/lisachenko/go-aop-php
    Official site: http://go.aopphp.com
    ZendFramework2 demo: http://zf2.aopphp.com/?aspect

    View Slide