Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемwww.phpconf.ru
1 Аспектно Ориентированное Программирование в PHP Щеваев Павел pachanga BIT, г.Пенза, Разработчик Limb PHP Framework
2 Как жаль, что мы не живем в идеальном мире!
3 + = Любовь и гармония…
4 Бесплатное пиво…
5 Поддержка namespace в PHP…
6 …и closures
7 class NewsController extends Controller { function create(){ $news = new News(); $news->setDate($this->request->get('date')); $news->setContent($this->request->get('content')); $news->save(); } Простая и понятная бизнес логика
8 Что является помехой? (Сквозной функционал)(Сквозной функционал) C ro s s c ut t ing C o n c e r n s
9 class NewsController extends Controller { function create(){ $ctx = AppContext :: instance(); if($ctx->isUserAuthorized()) { $news = new News(); $news->setDate($this->request->get('date')); $news->setContent($this->request->get('content')); $ctx->startTransaction(); try { $news->save(); $ctx->commitTransaction(); $ctx->log("News created successfully"); } catch(ValidationException $e) { $ctx->rollbackTransaction(); $ctx->log("News validation error"); throw $e; } else { throw new AuthException(); $ctx->log("Operation is not permitted"); } rollbackTransaction(); $ctx->log("News validation error"); throw $e; } else { throw new AuthException(); $ctx->log("Operation is not permitted"); }">
10 Лоскутное одеяло сквозного функционала
11 АОП спешит на помощь
12 class NewsController extends Controller { function create(){ $news = new News(); $news->setDate($this->request->get('date')); $news->setContent($this->request->get('content')); $news->save(); } Простая и понятная бизнес логика - 2.0
13 aspect Authentication{ pointcut controllerCreate:exec(public *Controller::create()); around(): controllerCreate{ $ctx = AppContext :: instance(); if($ctx->isUserAuthorized())) { proceed(); } else { $ctx->log("Operation is not permitted"); throw new AuthException(); } Аспект авторизации
14 aspect Transaction{ pointcut save:call(public News->save()); around(): save{ $ctx = AppContext :: instance(); $ctx->startTransaction(); try { proceed(); } catch (ValidationException $e) { $ctx->rollbackTransaction(); $ctx->log("News validation error"); throw $e; } Аспект транзакции
15 aspect Logging{ pointcut save:call(public News->save()); after(): save{ $ctx = AppContext :: instance(); $ctx->log("News created successfully"); } Аспект журналирования
16 Диаграмма последовательности 1 2 3
17 Непонятно? Немного теории (совсем чуть-чуть, честно!)
18 Введение в АОП AspectJ( – lingua franca в мире АОП Gregor Kiczales + команда XEROX PARC + желание облегчить нам жизнь = AspectJ
19 Базовые понятия JoinPoint PointCut Advice Introduction Aspect Weaving
20 JointPoint JoinPoint - фундаментальное понятие АОП, под которым понимают любую четко идентифицируемую точку исполнения программы JoinPoint точки являются кандидатами возможной инъекции сквозного функционала
21 JoinPoint Возможные JointPoint точки в примере: –выполнение метода credit() –доступ к атрибуту balance class Account { function credit($amount) { $this->balance += $amount; } 1 2
22 PointCut PointCut – набор(срез) JoinPoint точек, удовлетворяющих определенному условию. PointCut бывают именованные и анонимные. PointCut – это некое подобие SQL запроса для JointPoint точек –Пример анонимного среза, захватывающего исполнение метода Account :: credit() exec(Account::credit(*))
23 Advice Advice - код, выполняемый для каждой JoinPoint точки, входящей в определённый PointCut. Advice может выполняться до (before), после (after) или вместо (around) JoinPoint точки. Advice схож с традиционным ООП методом
24 Advice Пример Advice метода для анонимного PointCut среза before(): exec(Account::credit(*)) { echo("Сейчас будет выполнен метод credit"); } Пример Advice метода для именованного PointCut среза poincut credit : exec(Account::credit(*)) before(): credit { echo("Сейчас будет выполнен метод credit"); }
25 Introduction Introduction – инструкция для изменения статической структуры классов, интерфейсов и аспектов. –Попробуем добавить метод setLog() во все классы, которые начинаются со строкиFoo public function Foo*::setLog(Log $log){ $log->setLevel(Log::ALL); $this->log = $log; }
26 Aspect Aspect - модуль в терминах АОП, некоторый аналог класса, который инкапсулирует в себе правила применения сквозного функционала. Aspect - конечный контейнер для всех АОП элементов: PointCut, Advice и Introduction. Aspect схож с ООП классом (также позволяет объявлять и использовать обычные методы и атрибуты)
27 Aspect Пример аспекта(объединяем все вместе) aspect ExampleAspect { before(): exec(Account::credit(*)) { echo("Сейчас будет выполнен метод credit"); }
28 Weaving Weaving – процесс «вплетения» аспектов в логику приложения. Weaving процесс может происходить на уровне исходных кодов или же на уровне виртуальной машины (в случае PHP, это уровень исполнения opcode инструкций).
29 АОП - вид сверху (или сбоку?) Процесс разбиения функциональных требований на аспекты с их последующим сплетением в конечный код приложения
30 Фух...с теорией покончено
31 Средства АОП для PHP phpAspect – юная, но наиболее перспективная реализация АОП для PHP –Интересная попытка клонировать AspectJ –Аспекты вплетаются статически в код –Автор Willliam Candillon aoPHP – некое подобие АОП –Аспекты вплетаются «на лету» –Замороченный способ использования: Apache -> mod_rewrite -> aoPHP C++ интерпретатор -> PHP …бр-р-р) aspectPHP – форк aoPHP –Не обновлялась с 2005 г –Работает только с PHP AOP Library for PHP – спорная эмуляция АОП средствами PHP, –Автор некто Dmitry Sheiko runkit – PECL модуль, предоставляющий AOP Introduction возможности –Переопределение констант, функций, методов, классов, интерфейсов –Эх, жаль, что не в core –Автор Sara Golemon
32 # pecl install -f Parse_Tree # pear install PHP_Beautifier # pear install Console_GetOpt Установка:
33 Принцип действия:
34 $ php phpaspect.php $ php phpaspect.php –d src src bin Базовое использование:
35 АОП поддержка: –PointCut –Advice –Introduction –Aspect см. раздаточный материал за подробностями
36 HelloWorld (ну куда же без него) $ php hello.php Hello! src/hello.php
37 Пример аспекта src/trace.aspect.php
38 В действии $ php phpaspect.php src src bin $ php bin/hello.php After a construction of HelloWorld Before a saying of HelloWorld Around a saying of HelloWorld Hello! end around After a saying of HelloWorld Вплетение аспектов Выполнение переплетенного кода
39 « За кулисами» …
40 $phpaspect_56 = &$hello; $phpaspect_56 = $phpaspect_70; $phpaspect_87 = &$hello; if (isCallType($phpaspect_87, '*', 'say', 'say')) { $thisJoinPoint = new CallJoinPoint('', __LINE__, __FILE__, array(), $phpaspect_87, 'say'); function __phpaspectff f7e637a085e06b4bef62($thisJoinPoint) { echo "Before a saying of ". get_class($thisJoinPoint->getTarget()). "\n"; unset($thisJoinPoint); } __phpaspectff f7e637a085e06b4bef62($thisJoinPoint); } if (isCallType($phpaspect_87, '*', 'say', 'say')) { $thisJoinPoint = new CallJoinPoint('', __LINE__, __FILE__, array(), $phpaspect_87, 'say'); echo "Around a saying of ". get_class($thisJoinPoint->getTarget()). "\n"; $res = $phpaspect_87->say(); echo "\nend around\n"; $__return_result = $res; unset($thisJoinPoint); } else { $phpaspect_104 = &$phpaspect_87->say(); $__return_result = $phpaspect_104; } getTarget()). "\n"; unset($thisJoinPoint); } __phpaspectff7205121179f7e637a085e06b4bef62($thisJoinPoint); } if (isCallType($phpaspect_87, '*', 'say', 'say')) { $thisJoinPoint = new CallJoinPoint('', __LINE__, __FILE__, array(), $phpaspect_87, 'say'); echo "Around a saying of ". get_class($thisJoinPoint->getTarget()). "\n"; $res = $phpaspect_87->say(); echo "\nend around\n"; $__return_result = $res; unset($thisJoinPoint); } else { $phpaspect_104 = &$phpaspect_87->say(); $__return_result = $phpaspect_104; }">
41 Yikes! $phpaspect_104 = $__return_result; if (isCallType($phpaspect_87, '*', 'say', 'say')) { $thisJoinPoint = new CallJoinPoint('', __LINE__, __FILE__, array(), $phpaspect_87, 'say'); function __phpaspecte2600e1d66b7ca11ec71f56332b62ade($thisJoinPoint) { echo "After a saying of ". get_class($thisJoinPoint->getTarget()). "\n"; unset($thisJoinPoint); } __phpaspecte2600e1d66b7ca11ec71f56332b62ade($thisJoinPoint); } $phpaspect_104; ?> getTarget()). "\n"; unset($thisJoinPoint); } __phpaspecte2600e1d66b7ca11ec71f56332b62ade($thisJoinPoint); } $phpaspect_104; ?>">
42 Достоинства –Это сделали для PHP! –Наиболее схожая с AspectJ функциональность
43 Недостатки –На данный момент не подходит для production – некоторые аспекты вплетаются с ошибками (хотя чего мы хотим от версии 0.1.1?) –Функционально неполная реализация АОП (работа с аннотациями, расстановка приоритетов применения аспектов, наследование аспектов и проч.) –Генерируемый код накладывает негативный отпечаток на скорость работы
44 АОП – еще одна «серебряная пуля»? Конечно же нет, такой «пули не существует» Естественно есть ярые фанаты и отчаянные противники АОП –АОП, в самом деле, позволяет посмотреть на проблему сквозного функционала на качественно ином уровне –В то же время АОП местами нетривиальная и непрозрачная методология Как всегда, истина где-то посередине
45 АОП - достоинства Эффективно адресует проблему сквозного функционала Облегчает повторное использование кода - слабо связанные между собой аспекты легко взаимозаменять Позволяет отложить принятие спорного решения, касающегося работы всего приложения, на «потом»
46 АОП - недостатки Неочевидность происходящего (слишком много магии). Аспекты сложно (невозможно?) протестировать отдельно от сплетенного кода. Требуются отличные от ООП паттерны проектирования аспектов
47 «А оно вообще надо?» - решать исключительно вам :-)
48 Ссылки по теме AspectJ – phpAspect – aoPHP - aspectPHP - AOP Library for PHP - :// PECL runkit –
49 Вопросы?
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.