Что такое события (events) в MVC-фреймворках ?

программирование php framework фреймворк CakePHP

Что такое события (events) в MVC-фреймворках ? Как они обычно используются (приведите пример плиз) и насколько часто Вы их реально применяете ? Если можно поподробнее.

Примечание:
2 kotino:
я правильно понял, что, например, есть компонент, который способен генерить события, и есть много других компонентов, которые могут привязаться к факту генерации события первого компонента, чтобы когда первый компонент чихнул, все остальные заинтересованные сказали "Будь здоров!" ?

Если так, то опишите плз, как Вы реализуете хранение связей в интервалах между сеансами (согласитесь, восстанавливать их выполнением кода в каждом запросе - это очень накладно по времени), а также то, как собственно выглядит ссылка на компонент ?

Примечание:
2 kotino:
Я не очень хорошо знаю ZF, и цель изучать его сейчас не стоит, прошу объяснить просто, по рабоче-крестьянски... вы говорите, что линки событий создаются при инициализации модулей.
А как быть, если я не инициализирую те модули совсем, вот не нужны он мне пока. Например, у меня есть просто пустая страница, в генерации которой используется только один модуль "HelloWorld" и на которой выводится только надпись "Hello, world!" и под ней кнопка "Генерить событие".
Так вот, при нажатии на эту кнопку я по логике должен остаться на этой же странице, но эта кнопка должна дёрнуть все события в заинтересованных объектах. Как тогда будут вызваны обработчики в тех модулях, которые заинтересованы в обработке события, если я их не инициализирую (согласно иерархической структуре, поначалу я и не должен знать, что они заинтересованы, пока они не кинут линки, а они не кинут линки, потому что я их не проинициализирую).

Мне всегда нужно инициализировать все модули ?

Примечание:
2 kotino:

Ваша мысль ясна, тем не менее, не могу смириться с тем, что скрипт на каждом запуске будет инициализировать все модули. Это колоссальная трата времени, особенно если объектов несколько десятков, а действие скромное (например, обновление отображения какого-нибудь маленького контрола через AJAX).

Идеальной я вижу картинку, когда восстановление состояния каждого объекта (его переменных, связей и проч.) выполняется только для тех объектов, которые реально нужны для реализации текущего действия (Controller) и вывода (View). Пытаюсь найти конкретные примеры, но пока не могу найти.

Примечание:
Насчёт событийной модели через подписку (которую вы описали) - видимо, это наилучшая идея реализации event, причём не только в PHP MVC, но и на C# делается то же самое по сути, да и в Delphi. Теперь вопрос стоит только в том, чтобы как-то сохранять информацию о подписках в сессии между запусками скрипта...

Примечание:
2 kotino:

>>> Вполне логично предположить что для конкретного действия и вывода нужно где то сохранять события на которые он должен реагировать. Конкретно для меня (с моей логикой мышления) такой подход имеет один большой минус, подписка на события сосредотачивается не в одном месте, а размывается по коду. По опыту работы с Dojo (js фреймворк, располагающий к написанию кода работающего именно по событийной модели) не раз сталкивался с ситуацией когда бросаешь событие и получаешь как результата кота в мешке, из за того что кто то где то неудачно написал обработчик на событие. А вот что бы найти кто и где, нужно потратить достаточно много времени. Для меня стало гораздо удобнее инициализировать подписку на события где нибудь в одном месте.

А что же делать, если связей огромное количество и про их наличие/отсутствие "знают" только модули, которые отвечают за них ? При достаточно большом проекте файл, отвечающий за связи, может вырасти в нечто страшное. Кстати, когда вы добавляете очередной линк, вам ведь приходится указывать непосредственно экземпляр какого-то класса, т.е. самого модуля, а это значит, создание экземпляра со всеми вытекающими последствиями (т.е. для того, чтобы создать все связи, по сути приходится загружать весь проект на каждый даже самый мелкий запрос)! Вам это не кажется слегка избыточным ?

И ещё один ответ, на который я не могу найти ответа: как быть с динамическими связями. Приведу пример: мы создали два компонента, связали их линками событий и потом рраз, убили один компонент, который был "слушателем". Получается, что линк есть, а слушателя уже нет. И то, что мы можем перед вызовом обработчика проверить наличие слушателя и не вызывать обработчик если он грубо говоря никуда не ведёт - это полбеды; эта ситуация может породить большую кучу никуда не ведущих линков, которые будут захламлять пул сессии и оттягивать на себя одеяло производительности. Как вы решаете эту задачу ?

Примечание:
>>> То решением проблемы "динамических связей" (как вы ее назвали) может служить размещение в __destruct кода который отписывает объект от события. В таком случае убивая объект автоматически произойдет отписка от всех событий на которые он реагировал.

С этим ясно. Но всё же слегка смущает то, что в случае сбоя и не вызова __destruct(), несколько связей могут остаться в системе навечно. Тут нужен механизм похитрее....

Что вы в своей практике обычно считаете модулем ? Например, являются ли модулями следующие вещи:

1. Элемент формы для ввода текста и автоматической передачи его значения через AJAX на сервер (для сохранения значения в сессии);

2. Сложный контрол формы - например, кусочек "листабельной" карты Google Maps со строкой поиска, дерево с чекбоксами возле элементов; сложный контрол в виде двух листбоксов и кнопками [>>] и [<<] между ними, позволяющий набирать элементы из списка перекидыванием;

3. Форма с контролами;

4. Отдельная страница, включающая в себя некое содержимое с информацией и формами, но не включающая в себя шапку страницы;

5. Несколько страниц, имеющих общую функциональность и общую "шапку".

Используя ZF, или ваш движок, могу ли, я например, подвязаться к событию onChange контрола на форме, который находится на самом деле в одной из десяти форм части приложения, ответственной за регистрацию пользователя ? Или мне нужно все события внутренних контролов ремаппить (или как-то реализовать кодом) в события модуля, и только потом извне можно будет привязываться к ним ?

Примечание:
2 kotino:
Большое спасибо за интересный диалог, я убедился в том, что действительно правильно понимаю суть событий и их реализации в PHP-фреймворках, а также в принципах работы ZF.

К чему был задан такой глупый и наивный вопрос ? Меня интересовало мнение разных людей по поводу событий, быть может, если бы они были, то могли бы натолкнуть меня на некоторые прогрессивные идеи. Но пока что похоже я остаюсь на своём, а именно: попытке реализовать фреймворк, основанный на виртуальном длительном хранении иерархически связанных мелких законченных компонентов в специально организованном хранилище. Благодаря тому, что все компоненты имеют механизм непосредственной адресации, стала возможной недоступная в ZF (и других фреймворках) функциональность, такая как, например, восстановление из хранилища полного состояния конкретного компонента, а теперь, благодаря диалогу с вами, и восстановление событийных связей, ассоциированных именно с этим компонентом. Важно, что при восстановлении некоего компонента для произведения с ним действий, либо же задействовании его в выводе, абсолютно не затрагиваются остальные "спящие" компоненты, что теоретически позволяет строить неограниченные по масштабам приложения не теряя при этом в производительности.

Большое спасибо!
Ответы:
Скорее не ответ а общие мысли.
По сути события неважно в каком языке упираются в паттерны Observer и Mediator (терминология GoF).
Сейчас как раз занимаюсь тем что на php реализую что то на подобие http://www.artlebedev.ru/tools/technogrette/js/observable/.
Собственно зачем мне это понадобилось (работаю под Zend Framework).
Epsiloncool: я правильно понял, что, например, есть компонент, который способен генерить события, и есть много других компонентов, которые могут привязаться к факту генерации события первого компонента, чтобы когда первый компонент чихнул, все остальные заинтересованные сказали "Будь здоров!"
Epsiloncool - в моем случае модули инициализируется всегда. Это обусловлено логикой работы Zend Framework.
Т.е. сам фреймворк делает ряд служебных операций необходимых для нормальной работы модулей.
Epsiloncool: Идеальной я вижу картинку, когда восстановление состояния каждого объекта (его переменных, связей и проч.) выполняется только для тех объектов, которые реально нужны для реализации текущего действия (Controller) и вывода (View). Пытаюсь найти конкретные примеры, но пока не могу найти.
Если исходить из того что объект класса Event реализует паттерн "Одиночка", и информация о событиях-подписчиках сосредоточенна в одном месте. То решением проблемы "динамических связей" (как вы ее назвали) может служить размещение в __destruct кода который отписывает объект от события. В таком случае убивая объект автоматически произойдет отписка от всех событий на которые он реагировал.
На мой взгляд __destruct(), достаточно надежное решение, так как при уничтожение объекта он вызовется обязательно. Как в случае прямого уничтожения объекта, так и в результате работы сборщика мусора.


14 лет назад

RPI.su - самая большая русскоязычная база вопросов и ответов. Наш проект был реализован как продолжение популярного сервиса otvety.google.ru, который был закрыт и удален 30 апреля 2015 года. Мы решили воскресить полезный сервис Ответы Гугл, чтобы любой человек смог публично узнать ответ на свой вопрос у интернет сообщества.

Все вопросы, добавленные на сайт ответов Google, мы скопировали и сохранили здесь. Имена старых пользователей также отображены в том виде, в котором они существовали ранее. Только нужно заново пройти регистрацию, чтобы иметь возможность задавать вопросы, или отвечать другим.

Чтобы связаться с нами по любому вопросу О САЙТЕ (реклама, сотрудничество, отзыв о сервисе), пишите на почту [email protected]. Только все общие вопросы размещайте на сайте, на них ответ по почте не предоставляется.