Комментарии 41
> Судя по популярности в Java, парадигма довольно интересная и имеет право на жизнь в PHP.
Эту фразу можно сказать о чём угодно, и получится неверно.
Судя по популярности в Java, парадигма довольно популярна в Java.
А интересная парадигма или нет, и имеет ли она право на жизнь в PHP, никак с популярностью в Java не связано. Может быть, интересная, может быть, нет, может быть, имеет право на жизнь, может быть, нет. Но об этом нужно отдельно рассуждать.
Эту фразу можно сказать о чём угодно, и получится неверно.
Судя по популярности в Java, парадигма довольно популярна в Java.
А интересная парадигма или нет, и имеет ли она право на жизнь в PHP, никак с популярностью в Java не связано. Может быть, интересная, может быть, нет, может быть, имеет право на жизнь, может быть, нет. Но об этом нужно отдельно рассуждать.
Была давненько статья с презентацией библиотеки, реализующей эту парадигму в php. Это работало как постобработка кода, то есть вы пишете пишете используете красивые конструкции которых нет в языке, потом прогоняете код парсером и все работает, но код — лапша.
Парадигма интересная, но лично мне страшно что-то такое использовать в production. Было бы хотя бы расширение или смутные намеки, что это запилят в x.x версии языка.
Парадигма интересная, но лично мне страшно что-то такое использовать в production. Было бы хотя бы расширение или смутные намеки, что это запилят в x.x версии языка.
Расширение то есть(описаное в статье), но оно конечно пока сырое, до продакшена еще далеко.
2005 последнее обновление. Вы же понимаете, что это мертвый код.
Это Intercept обновлялось в 2005, на базе него я разработал свое(MethodIntercept), которое обновлялось позавчера). Если окажется кому-то нужным, могу занятся разработкой и поддержкой.
доклад АОП в PHP, который был аж на PHPConf2007 (слайды доступны тут wiki.agiledev.ru/doku.php?id=conferences), мне кажется более полно раскрывает + данного подхода.
из рассмотренных тогда способов реализации wiki.agiledev.ru/doku.php?id=aop:aop_php#средства_аоп_для_php сейчас не работает ни один.
третий способ реализации на php — парсерить php код и генерировать на его основе другой php код, который выполняет обёртки
из рассмотренных тогда способов реализации wiki.agiledev.ru/doku.php?id=aop:aop_php#средства_аоп_для_php сейчас не работает ни один.
третий способ реализации на php — парсерить php код и генерировать на его основе другой php код, который выполняет обёртки
вроде все проекты сдохли, code.google.com/p/php-aop/source/list датируется 2008 годом последний коммит. видимо на определённом этапе интерес пропадает :)
> вроде все проекты сдохли
Вот здесь посмотрите еще — wiki.agiledev.ru/doku.php?id=aop:aop_php — некоторые проекты вроде еще живы.
Вот здесь посмотрите еще — wiki.agiledev.ru/doku.php?id=aop:aop_php — некоторые проекты вроде еще живы.
Вот точная ссылка на список — wiki.agiledev.ru/doku.php?id=aop:aop_php#средства_аоп_для_php
Я эти аспекты заменил евентами, на каждый пук фреймверк посылает евент, остальные, кому надо на них подписываются, yii и ZendFramework 2 так же работают, и это, как по мне, удобней и проще.
«Судя по популярности.....»
Насколько я знаю, AOP в «традиционных» языках имеет весьма ограниченное применение в силу того, что очень легко так, что код один, а происходит совсем другое. В Java — это отчасти компенсируется IDE которая подсказывает, что вот «здесь» ещё и аспекты вызываются. На даже не смотря на поддержку IDE — применение аспектов обычно ограничивается: логированием, декларативным управлением транзакциями, кешированием.
Но юмор ситуации в том, что если мы в архитектуре опираемся на SOLID, то декларативное управление транзакциями, кеширование и отчасти логгирование — мы можем легко и явно (или чуть менее явно — внутри IOC-контейнера) реализовать и без аспектов. Так так ли нужны аспекты в php?
Насколько я знаю, AOP в «традиционных» языках имеет весьма ограниченное применение в силу того, что очень легко так, что код один, а происходит совсем другое. В Java — это отчасти компенсируется IDE которая подсказывает, что вот «здесь» ещё и аспекты вызываются. На даже не смотря на поддержку IDE — применение аспектов обычно ограничивается: логированием, декларативным управлением транзакциями, кешированием.
Но юмор ситуации в том, что если мы в архитектуре опираемся на SOLID, то декларативное управление транзакциями, кеширование и отчасти логгирование — мы можем легко и явно (или чуть менее явно — внутри IOC-контейнера) реализовать и без аспектов. Так так ли нужны аспекты в php?
Тут скорее стоит задать вопрос так — «Нужны ли аспекты вообще?», потому что php язык себе как язык.
Мне лично понравилась статья от IBM — www.ibm.com/developerworks/ru/library/j-aopwork15/
Они как раз утверждают что «применение аспектов обычно ограничивается» ваше неверно.
Мне лично понравилась статья от IBM — www.ibm.com/developerworks/ru/library/j-aopwork15/
Они как раз утверждают что «применение аспектов обычно ограничивается» ваше неверно.
> Они как раз утверждают что «применение аспектов обычно ограничивается» ваше неверно.
Пробежался по статье по диагонали. Нашёл много текста говорящего о том, что «мол да — не ограничивается, что для аспектов есть много других хороших применений», но не нашёл ни одного убедительного примера. В случае с фильтром попытка показать преимущества аспектной реализации перед реализацией интерфейса выглядит надуманной.
Если у вас есть материалы об успешном использовании аспектов — будет интересно узнать (только просьба — больше не кидать ссылки на документы подобные тому с ibm)
Причём — если в java реализация динамических прокси выглядит обычно пугающе, то в php подобная техника является обычным делом благодаря magic-методам.
Пробежался по статье по диагонали. Нашёл много текста говорящего о том, что «мол да — не ограничивается, что для аспектов есть много других хороших применений», но не нашёл ни одного убедительного примера. В случае с фильтром попытка показать преимущества аспектной реализации перед реализацией интерфейса выглядит надуманной.
Если у вас есть материалы об успешном использовании аспектов — будет интересно узнать (только просьба — больше не кидать ссылки на документы подобные тому с ibm)
Причём — если в java реализация динамических прокси выглядит обычно пугающе, то в php подобная техника является обычным делом благодаря magic-методам.
А питоновские декораторы служат для этой же цели или это другая парадигма?
А почему не сделать, чтобы в совет объект и параметры метода, приходили как два разных параметра, а не один массив?
Для единообразия.
В пхп уже принято так передавать методы в качестве параметра.
В пхп уже принято так передавать методы в качестве параметра.
А где это написано как а пхп принято?
Например в магическом методе
название метода и список аргументов разделены на два разных параметра, разве это не пример того как принято?
И мне непонятна эта строчка github.com/kooler/PAF/blob/master/Framework/paf/joinpoint.php#L97
В чем смысл использовать eval, когда можно написать
Когда в ход идел eval() — дело пахнет жареным.
И наконец вместо написания комментария
Если можно просто финализировать конструктор:
Например в магическом методе
public function __call($method, array $args) {}
название метода и список аргументов разделены на два разных параметра, разве это не пример того как принято?
И мне непонятна эта строчка github.com/kooler/PAF/blob/master/Framework/paf/joinpoint.php#L97
public function fire($arguments) {
$funcCreation = '$ob=new '.$this->getCallClassName().'();$ob->'.$this->getCallMethodName().'($arguments);';
eval($funcCreation);
}
В чем смысл использовать eval, когда можно написать
public function fire($arguments) {
$objClass = $this->getCallClassName();
$obj = new $objClass;
call_user_func_array(array($obj, $this->getCallMethodName()), $arguments);
}
Когда в ход идел eval() — дело пахнет жареным.
И наконец вместо написания комментария
/*
* Base aspect class. Must be extended in all aspects
* IMPORTANT: Each aspect should have constructor without arguments
*/
abstract class Aspect {};
Если можно просто финализировать конструктор:
/*
* Base aspect class. Must be extended in all aspects
* IMPORTANT: Each aspect should have constructor without arguments
*/
abstract class Aspect {
final public function __construct() {}
};
Спасибо за замечания касательно eval и финализации конструктора, исправлю.
Насчет параметров совета — планирую в следующей версии модуля сделать аналогично методу __call.
Сначала планировал передавать больше информации в совет, поэтому и сделал в виде массива, чтобы проще было расширить. Но немного поработав с модулем вижу, что кроме обьекта и аргументов ничего не нужно, поэтому решил переделать, пока он еще на ранней стадии и никем не используется.
Насчет параметров совета — планирую в следующей версии модуля сделать аналогично методу __call.
Сначала планировал передавать больше информации в совет, поэтому и сделал в виде массива, чтобы проще было расширить. Но немного поработав с модулем вижу, что кроме обьекта и аргументов ничего не нужно, поэтому решил переделать, пока он еще на ранней стадии и никем не используется.
>> А где это написано как а пхп принято?
ru.php.net/manual/en/language.pseudo-types.php#language.types.callback
Только имени метода достаточно, если мы уже знаем, в каком мы классе
ru.php.net/manual/en/language.pseudo-types.php#language.types.callback
Только имени метода достаточно, если мы уже знаем, в каком мы классе
Ванга видит как охуенно такой код дебажить.
мне не нравится парадигма АОП, так как основное требование к большинству проектов — это скорость выполнения.
Внедрять парадигму АОП надо как-то на уровне Zend Egine, как точно я пока не знаю.
Внедрять парадигму АОП надо как-то на уровне Zend Egine, как точно я пока не знаю.
Расширения Intercept и MethodIntercept так и делают. Они заменяют функцию вызывающую методы\функции оберткой, соответственно вызов советов выполняется на уровне Zend Engine.
Хм, как мне кажется основное требование давно скорость разработки и, главное, простота (включая скорость) поддержки и развития. И если со скоростью разработки явных преимуществ не видно, то если вот, например, внезапно для проектировщика добавить то же логирование каждого чиха — преимущества АОП, имхо, очевидны, если каких-то хуков и евентов архитектурой не предусмотрено.
Не всегда. В высоконагруженных проектах, оплата за процессорное время может запросто обогнать затраты на разработку. Я работал в проекте, где 10% снижение нагрузки означало экономию в 50 000$
Не люблю АОП — слишком много магии в коде. Вот вроде класс как класс, ан нет — там еще 100500 функций вызывается неизвестно где
А нет ли желания добавить поддержку annotations так, как это сделано в C#?
Когда-то бы статья, быть может даже здесь на Хабре. Элегантная иньекция сквозной функциональности. Возможно если поработать с кодом, можно выйти на фреймворк, если вдруг никто этого еще не сделал.
class Event extends ArrayObject {
public function __invoke() {
foreach($this as $callback)
call_user_func_array($callback, func_get_args());
}
}
$test = new Event();
/* Setting up callbacks */
$test[] = function($msg, $txt) {
echo "This is the event!
";
};
$test[] = function($msg, $txt) {
echo "Message: $msg. Text: $txt
";
};
$test[] = function($msg, $txt) {
echo "Works great!
";
};
/* call */
$test("Some message", "Some text");
Я не понял главного. Как осуществляется связь обслуживаемый метод -> аспект? Ну то есть, каким образом синтаксически задаётся, что для метода Backet::order() нужно вызывать конкретный аспект после выполнения метода?
У меня три предположения. Вот ваш код:
Вариант 1. Связь задаётся через комментарий. Ваша библиотека ищет комментарий вида "@After(Backet->order)" и благодаря ему знает, что код ниже должен срабатывать после метода Backet::order().
Вариант 2. Связь задаётся через имя метода backetOrderMessage. Первое слово — класс (backet), второе слово — метод (order), третье слово — тип аспекта (message), видимо message — это тип пост-аспекта, т.е. который срабатывает после метода.
Вариант 3. Вы забыли показать кусок кода, в котором происходит связь метод->аспект.
Пожалуйста, проясните данный вопрос.
У меня три предположения. Вот ваш код:
/*
* @After(Backet->order)
*/
public function backetOrderMessage($params) {
echo ‘Backed has been ordered’;
}
Вариант 1. Связь задаётся через комментарий. Ваша библиотека ищет комментарий вида "@After(Backet->order)" и благодаря ему знает, что код ниже должен срабатывать после метода Backet::order().
Вариант 2. Связь задаётся через имя метода backetOrderMessage. Первое слово — класс (backet), второе слово — метод (order), третье слово — тип аспекта (message), видимо message — это тип пост-аспекта, т.е. который срабатывает после метода.
Вариант 3. Вы забыли показать кусок кода, в котором происходит связь метод->аспект.
Пожалуйста, проясните данный вопрос.
Связь задается при помощи аннотаций — определенного формата комментариев.
Таким образом аннотация вида:
значит, что совет backetOrderMessage нужно вызвать после выполнения метода order обьектов класса Backet.
Более детально о возможных аннотациях можно почитать в документации на Гитхабе: github.com/kooler/PAF/wiki/PAF-Join-points
Таким образом аннотация вида:
/*
* @After(Backet->order)
*/
public function backetOrderMessage($params) {
echo ‘Backed has been ordered’;
}
значит, что совет backetOrderMessage нужно вызвать после выполнения метода order обьектов класса Backet.
Более детально о возможных аннотациях можно почитать в документации на Гитхабе: github.com/kooler/PAF/wiki/PAF-Join-points
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
PHP и Аспектно-ориентированное программирование