Upload
alexander-lisachenko
View
815
Download
0
Embed Size (px)
DESCRIPTION
Presentation about aspect-oriented programming in PHP with Go! framework on DevConf-2013 conference.
Citation preview
Аспектно-ориентированное программирование в PHP
Лисаченко Александр, архитектор web-приложений Alpari-RU
О докладчике
Лисаченко Александр
• Архитектор веб-приложений в Alpari• Опыт работы во всех основных
направлениях PHP-разработки (highload, бизнес-приложения, веб-сервисы, соц. сети)
• Идеолог Symfony2: почти десяток внутренних сервисов на Symfony2, в т.ч. и основной сайт alpari.ru (CDN, Varnish+ESI, Twig, Assetic, ~60 сабмодулей, ~20 бандлов)Twitter: @lisachenko
Github: https://github.com/lisachenko
Эволюция технологий
Машинное программирование
Структурированное программирование
Процедурное программирование
Модульное программирование
Объектно-ориентированное программирование
???
Логические единицы кода
• Функции• Процедуры
Процедурное
• Модули
Модульное
• Классы• Методы• Свойства
ООП
Принцип единственной отвественности
Принцип единственной отвественности
Сквозная функциональность
Сквозная функциональность
Сквозная функцио- нальност
ь
Авторизация
Обработка ошибок
Кэширование
Ведение логов
Управление авторизацией
Журналирование
Обработка ошибок
Матрешка функциональности
Авто-ризаци
я
Логиро-ваниеОбра-ботка ошибо
к
Основ-ной код
Почему это плохо?
Плюсы:• Видна вся логика
метода
Минусы:• Код нельзя
использовать повторно
• трудно понять исходное предназначение класса
• запутанная логика• больше вероятность
допустить ошибку, забыв вписать «шаблонный» код
• нарушение принципа DRY
Аспектное программирование
Процедурное программирование
ООП
АОП
Аспектно-ориентированное программирование
АОП - методика программирования в рамках классовой парадигмы, основанная на понятии аспекта — блока кода, инкапсулирующего сквозное поведение в составе классов.
Аспектно-ориентированное программирование
Методология АОП была предложена группой инженеров исследовательского центра Xerox PARC под руководством Грегора Кичалеса (Gregor Kiczales).Ими же было разработано аспектно-ориентированное расширение для языка Java, получившее название AspectJ — (2001 год).
Аспектно-ориентированное программирование
АОП дает возможность вызвать дополнительный код (хук) в определенный момент работы программы: до выполнения метода, после выполнения метода, при обращении к свойству и другим без изменения исходного кода программы!
Ключевые понятия и термины
Аspect-Oriented Program-
ming
Joinpoint
Pointcut
Advice
Aspect
Introduction
Ключевые понятия и термины
Aspect
• Модуль или класс, реализующий сквозную функциональность.
• Аспект изменяет поведение остального кода, применяя совет в точках соединения, определённых некоторым срезом
Advice (совет)
• Дополнительная логика, которая должна быть вызвана из точки соединения
Ключевые понятия и термины
Joinpoint
• Точка в выполняемой программе, где следует применить совет
• Выполнение метода, обращение к свойствам объекта и др.
Pointcut (срез)
• Набор точек соединения. • Срез определяет, подходит
ли данная точка соединения к данному совету
Пример: паттерн FluentInterface
Method execution joinpoint
Property access joinpoint
Пример: паттерн FluentInterface
Advice
Pointcut definition
Aspect class
Процесс вплетения кода
Перехват include/requir
e
Stream wrapper
(php://filter)
Статический анализ кода
(token_get_all)
TokenReflection
Анализ Pointcut-ов
Модификация исходного
кода
Пример: паттерн Fluent Interface
Around advice
Original methodOriginal method AOP
Фреймворк Go! AOP PHP• Не использует PHP-расширений, целиком написан на
самом PHP;• Может быть использован с любым приложением на
PHP;• Оптимизирован (ленивая загрузка ядра,
кэширование классов, поддержка опкод-кэшеров)• Не требует DI-контейнера для подмены сервисов
прокси-объектами;• Может перехватывать динамические и статические
методы, методы в финальных классах, а также методы в трейтах;
• Может перехватывать обращения к публичным и защищенным полям;
• Чистый генерируемый код, удобно проводить отладку классов и аспектов с помощью XDebug
Срезы точек в Go! AOP PHP1. Выполнение методов
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)
Типажи (trait) в PHP – хорошо или плохо?
Хорошо Плохо
Проблема с тестированием
Нельзя динамически
изменить
Статическая зависимость
Множественное
наследование
Выносим общий код
Пример: trait + interface + AOP = Introduction
Introduction
• возможность динамически подключать интерфейсы и типажи к конкретному классу.
Пример: trait + interface + AOP = Introduction
Исходный класс•Обратите внимание, что мы не имплементриуем интерфейсов и не подключаем типажи в исходном классе.
Пример: trait + interface + AOP = Introduction
Класс после вплетения кода•К классу был добавлен динамически заданный интерфейс и типаж
Пример: логирование на уровне приложения
Пример: логирование на уровне приложения
За и против глобальных срезов
За•Позволяет сделать срез в любом коде, даже стороннем•Легко описать нужный неймспейс•Быстрота внедрения•Не нужно менять исходный код вообще
Против•Action at a distance – непредсказуемые эффекты в коде методов•Цепляет и нужное и ненужное•Может немного замедлить приложение из-за большого количества точек•Высока вероятность допустить ошибку
Пример: логирование на уровне приложения
Контроллируемые срезы
За•Используются стандартная технология интерфейсов-маркеров и срез within(InterfaceName+)•Используются наглядные аннотации-маркеры перед методами и срез @annotation(ClassName)•Влияют только на указанный разработчиком код (ожидаемое поведение)
Против•Необходимо вносить небольшие правки в исходный код•Ограниченная возможность работать с сторонним кодом
Проблема с доступом к состоянию объекта
1. Как вы уже наверное поняли, основное достоинство настоящего АОП – это возможность дополнять логику методов или целого класса дополнительным функционалом без изменения исходного кода.
2. Но класс аспекта является внешним по отношению к классу перехватываемого объекта, а значит, мы можем пользоваться только публичными данными объекта, а что делать если нужно обратиться к приватным или защищенным полям или методам объекта?
Привилегированные советы
Привилеги-
рованный совет
• Совет (метод) в классе аспекта, который выполняется в области видимости текущего объекта и имеет доступ к приватным и защищенным полям и методам класса
Попробуем считать поле $name в совете
Обычный совет работает согласно scope
Привилегированный совет
Привилегированный совет в scope объекта
АОП – следующий шаг в развитии PHP
ООП
Абстракция сервисов (yaml, xml,
php)
Внедрение зависи-мостей
(IoC, DIC)
Аспектно-ориентиро-
ванное программи-рование
AOP: за и против
За•Управление сквозной функциональностью•Снижение стоимости разработки•Более прозрачный код логики•Уменьшение шаблонных ошибок•Уменьшение связанности классов•Повторное использование кода
Против•Порог вхождения•Неявные эффекты•Ограниченная помощь IDE•Незначительное снижение скорости выполнения кода
Благодарю за внимание!Go! AOP PHP: https://github.com/lisachenko/go-aop-php
Official site: http://go.aopphp.com
ZendFramework2 demo: http://zf2.aopphp.com/?aspect