Любой, кому приходилось участвовать в разработке тиражируемых программных продуктов, знает насколько это не просто решить проблему обновления версий продукта. Конечно, все мы знаем о наличие специального программного обеспечения для контроля версий, например о CVS (Concurrent Versions System, http://en.wikipedia.org/wiki/Concurrent_Versions_System) и SVN. Однако проблем в том, что каждый новый продукт на базе нашего тиражируемого продукта требует дальнейшей адаптации и системы контроля версий едва ли помогут разрешить все конфликты при обновлении модифицированной (адаптированной) системы. Наверняка кто-нибудь из вас встречался с проблемой, когда после очередного обновления версии базового продукта, приходилось восстанавливать весь проект из резервных копий. А представьте себе ситуацию, когда «пропажа» адаптации в отдельных интерфейсах проекта выясняется спустя продолжительное время после обновления версии базового продукта! Вы скажите «А причем здесь АОП?!». Дело в том, что АОП как раз может помочь в решении данной проблемы.
Аспект ориентированное программирование позволяет выделить сквозную функциональность (функциональность, распределенную по всем модулям системы) в отдельные декларации – аспекты. Можно определить функциональность для строго заданных точек выполнения программы JoinPoints (определенная в коде точка, вызов метода, инициация класса, доступ к полю класса и т.д.). В языках, поддерживающих АОП, чаще используются назначения для множества точек - Pointcut. Функциональность в точках определяет программный код, который принято вежливо называть Advice (AspectJ). Таким образом, в пространстве аспектов описывается сквозная функциональность для определенного множества компонентов системы. В самих компонентах представлена лишь бизнес-логика, которую они призваны реализовать.
Все это замечательно, но как реализовать безопасное обновление системы в условиях беспрерывной адаптации?! Мы определяем некоторый аспект адаптации (например, дополнительная колонка в административных отчетах), определяем область актуальности аспекта (pointcut) и назначаем заданным событиям свои обработчики. Это может быть событие «Получены данные таблицы отчета». В таком случае обработчик проанализирует поток данных и добавит новую колонку.
Полагаю сложно почувствовать подход, описанный лишь теоретически. Давайте посмотрим как он реализуется в PHP. Загружаем библиотеку http://www.phpclasses.org/browse/package/2633.html и рассматриваем пример sample.php.
Представим что все классы нашей системы, требующей безопасного обновления оформлены подобно классу Sample: вход и выход каждого метода помечен Advice::_before($this) и Advice::_after($this). Кроме того, ключевые события системы отмечены как Advice::_event("Идентификатор_события", $this). Также, при загрузке библиотек системы, помимо прочего опрашивается скрипт plugins/index.php. Теперь допустим, на базе этой системы собираются проекты и один из них потребовал адаптации. Мы определяем в plugins/index.php аспект адаптации и область его актуальности.
$aspect1 = new Aspect();
$pc1 = $aspect1->pointcut("call *::*");
Далее мы определяем интересующие нас события
$pc1->_before("increment($obj, 'aspect1 Preprocessor');");
$pc1->_event("SomeEvent", "increment($obj, 'aspect3 specified event');");
Дописываем новый обработчик этих событий
function increment(&$obj, $param2) {
print "<div style="color: gray;">{$param2}, Environment Status: ".( $obj->env_var1)." </div>";
}
И применяем аспект
Aspect::apply($aspect1);
Рис. 1 aopupdate.gif
Как вы понимаете, в функции обработчика мы вольны использовать методы, переданного класса, а также модифицировать его переменные. Осталось лишь подключить фантазию и оценить, какие новые перспективы открываются перед вами.
Подробнее об АОП можно узнать здесь http://www.cmsdevelopment.com/ru/articles/aosdinphp/
Ссылки по теме
http://en.wikipedia.org/wiki/Aspect-oriented_programming
Аспектно-ориентированное программирование и PHP
Скрипты приведенного здесь примера