![]() |
Организация работы событий
Здравствуйте.
Интересует следующий вопрос, скорее даже нюанс проектирования приложений: 1) Допустим, у нас есть какой-то объект, который генерирует большое количество событий (больше 10). 2) Большинство из этих событий однотипные и через эти события не должны передаваться параметры. 3) Через некоторые события должны передаваться параметры, которые неотрывно привязаны к событию. Под параметрами, в данном контексте, я понимаю public переменные, которые можно считывать наподобие свойств target и/или delta у MouseEvent. Возникает вопрос: что делать, создавать 10 классов для каждого типа событий, каждое событие которого бы обладало только теми параметрами (читай открытыми свойствами), которые принадлежат к данному типу события, или целесообразней, в целях «не плодить большого количества классов и сэкономить время» сделать 1 класс события, указать в нём все свойства, которые могут быть необходимы для событий и устанавливать значения только для тех событий, которые будут нужны в каждом конкретно случае? Я, пока, склоняюсь ко 2-му способу, ведь, на сколько я понимаю, даже в MouseEvent сделано таким образом, что свойство delta доступно и при событиях CLICK, MOUSE_DOWN и т.п., хотя фактически оно необходимо только у события MOUSE_WHEEL. Но с другой стороны, все нюансы по работе событий будут известны мне, но другие люди, которым, возможно, придётся столкнуться с моими событиями, будут недоумевать, почему в одном случае есть информация об одних переменных, а в другом её нет. Вот такие вот дела. |
Только не public переменные, а геттеры
|
Цитата:
А я дурак, я делаю одно событие с var info:Object={} куда пишу всё что сдумается. :D На самом деле просто посмотри, что ты там передаешь с событием. Например, количество игроков онлайн, открытые двери и год после рождества Христова. По сути, 3 разных переменных - totalOnline, openDoors, year, но ведь можно передать просто intValue, а в комментариях написать мол "а тут нам приходит..." |
2 PsyhoTiger:
Мне кажется ваш подход в корне не правилен. Цитата:
Плюс непонятные названия переменных будут усиливать неразбериху. 2 fljot: Цитата:
|
Да.
Какие плюсы я вижу: типизация и использование одного события для многих задач. В коде: Код AS3:
Я не говорю, что мой вариант лучший - но он вполне имеет право на жизнь. Но, как я уже сказал, я всё равно пользуюсь одним Object`ом ) |
Каждому — своё, но мне кажется, что вариант с object, в этом случае, не имеет права на жизнь (я понимаю, что это звучит категорично, но мне кажется, что хорошо когда нам компилятор будет сам подсказывать, к каким переменным можно обратиться, а к каким — нет + хорошие названия переменных улучшают читабельность кода).
Такие моменты, на мой взгляд, становятся важны когда работаешь в команде или создаёшь что-то, чем будут пользоваться другие люди, если работаешь один, то на это можно забить, но это не значит, что так нужно/следует поступать. |
Цитата:
|
Цитата:
|
Цитата:
|
Да, etc прав. Вся инкапсуляция и тому подобное было сделано ради защиты от дураков. Защиты от идиотов же не существует. Я найду способ сломать событие и с геттерами. Например, остановлю его.
|
По моему скромному мнению, если у нас нет жестких ограничений по производительности, то чем полнее информация в событии, тем лучше. Все-таки xml/json рулит по сравнению с набором безымянных чисел, всплывших неизвестно откуда и неизвестно по какой причине.
Продал твой фермер корову вместе с попоной на колбасу, сервер вернул информацию о том, что сделка акцептована, ты сформировал хорошее такое событие с xml-кой внутри, прогнал его не задумываясь по всем объектам (касса, хлев, склад, производственный план, что там еще), и все счастливы. Каждый объект взял из него то, что его касается, и все аккуратненько и синхронно обновилось. Но, это лично мне так нравится. Совсем не обязательно, что так правильно. |
mikhailk, у нас речь не о обмене сервер-клиент, а о событиях в самой флешке. Наследники flash.events.Event так сказать)
|
Если все события генерирует один объект, то можно предположить, что все параметры передаваемые через события как то связаны или имеют принадлежность к какой то сущности. Можно сделать и один класс события в котором будет один параметр представляющий собой класс, который содержит в себе нужные строго типизированные свойства (т.н. value object). Т.е решение подобное ому как делает Psycho Tiger, только не в ущерб типизации, автокомплита и т.д.
|
2 Mur4ik:
Как мне кажется, ваш вариант подходит в том случае, если этот объект с типизированными переменными будет использоваться ещё где-нибудь (допустим его будут передавать в качестве параметра для создания объектов на основе этого объекта), иначе, как мне кажется, нет смысла переносить список переменных из Event объекта в какой-то другой объект, потому что по сути добавляется только 1 промежуточный этап на пути доступа к переменным. |
Не спорю.
Просто если параметры передаваемые событием связаны, то мне удобнее видеть их в одном объекте, который их характеризует, вместо того чтоб в классе события создавать 5-10 параметров, с которыми работа только усложняется, особенно в случае когда нужно передать большую часть из этих параметров (имеется ввиду инициализация события). А вот имея один-два типизированных объекта все становится прозрачнее и удобнее, ИМХО. |
Цитата:
Цитата:
Если все правильно про клонирование, то как/когда это происходит при нативном всплытии события? :o Вот пример того, что наблюдаю я: Код AS3:
Код AS3:
|
Попробуйте сделать
Код AS3:
|
да, при редиспатче поюзанного эвента - он клонируется. Видимо, идет проверка а-ля:
Код AS3:
Но не суть. Из контекста приведенных мною цитат ниразу не понятно, что идет редиспатч. Скорей наоборот - речь об обычном распространении события. А при нем, как показывают тесты, клонирования события от обработчика к обработчику не происходит. Собственно, по этому поводу я и ожидал комментариев. |
Хм да, я тоже несколько удивлён=) etc, не разъяснишь?
|
Событие клонируется при нативном EventDispatcher::dispatchEvent`е.
|
Цитата:
|
Вы имеете ввиду, если вызвать метод EventDispatcher#dispatchEvent, то внутри него произойдет event.clone();
|
Цитата:
И вот только оно клонируется всегда, даже при первом вызове dispatchEvent`а. Короче, то что сказал dimarik. |
Цитата:
Цитата:
Цитата:
Код AS3:
Цитата:
|
Ого, и вправду. Ошибался, спасибо, буду знать. А второе событие уже клон.
Видимо событие несёт в себе какой-то флаг а-ля isUsed, и раздваяйца оно только если событие уже было использовано. Цитата:
|
Цитата:
Собственно, под эгидой этого топика я надеялся избавиться от геттеров в сложных событиях (наступление которого ожидают несколько объектов/обработчиков). Но, видимо - не судьба. "Не клонируется", раз... "Не клонируется", два... "Не клонируется", три... Пр...:D P.S. оффтоп. Даный топик имеет тег "Лень", по которому в поиске пробивается только этот топик. Забавно )) |
switcher, геттеры (ридонли) - это лишь перестраховка в 99% случаев, чтобы случайно что-нибудь не изменить - чисто по запарке.
|
разумеется, но я эту "перестраховку" вывел в стандарт. В простых нотификациях можно и открытыми переменными обойтись, ибо плевать, что обработчик с объектом события сделает. Оно (событие) ему только и предназначается.
Однако в сложных, когда подписчиков много, я не хочу держать в голове: что я могу, а что не могу делать с полями объекта события. Я хочу быть уверенным, что объект как неизменный штамп события дойдет до адресата в том виде, в каком он изначально описывает событие. А так, конечно, можно все переменные пабликами делать, из детей родителями управлять и т.д. => главное, "чисто по запарке" не запутаться :) P.S. Я не занимаюсь миссионерством. Если кого-то сей подход не устраивает, пожалуйста, пожалуйста... |
Клонирование события происходит при наличии у диспетчера parent и если выставлен флаг bubbles?
|
неа, пока установлен только один случай, когда происходит клонирование события. Это повторный диспатч того же объекта события.
|
ок.
Код AS3:
|
в яблочко
|
Собственно, резюме. Если у события target != null, то при диспетчеризации оно клонируется.
В моем примере флаг bubbles не имеет значения. |
Цитата:
dimarik, раз уж такое дело - хотелось бы знать, реализация клонирования эвента в ваших моделях(Data) на каждом уровне "всплытия" (при наличии обработчиков) целесообразна? Так и задумывалось? Или проглядели, что в нативной системе эвент при баблинге не клонируется? (я должен был спросить, вдруг прокатит :D) |
Уточнение. Клонирование скорее всего необходимо при event.target != null && event.target != this.
В нативной системе при диспатче (напр., Event.ADDED) не дергается dispatchEvent вообще. Соответственно, такая проверка не вызывается и событие не клонируется. У нашей Data клонируется, как Вы и указали, если среди прочих условий соблюдено parent.hasEventListener(event.type). И target клона устанавливается текущим диспетчером. |
Цитата:
Цитата:
По остальному: так ведь у вас целевой эвент не баблится непосредственно. Для этого у него есть эвент-обертка. Но вы все равно клонируете целевой эвент на всех уровнях (при наличии слушателей), который вообще не диспатчится. Он тащится наверх эстафетой из оберток. Смысл его клонировать? |
Цитата:
Я пытаюсь рассуждать как должно быть, а не как это реализовано в FP. Если мы поймем зачем нужно клонирование событий, то его можно реализовать оптимальным способом. Клонирование само по себе необходимо для предотвращения изменений объекта по ссылке. Сравните: передали методу массив и он модифицировал его. А в вызывающем методе Вы предполагали, что он не изменится. Выход - либо передаем клон, либо в вызванном методе создаем клон. С другой стороны, конкретно в области event flow при выполнении диспетчеризации у событийного объекта должен быть установлен target того, кто его испустил. Здесь получается, что если бы не было клона, то неожиданно у всех предыдущих объектов-приемников поменялся бы event.target по ссылке. Но я диспатчу событие от того же передатчика. Здесь мне не нужен клон. Если я диспатчу событие, то мне будет важнее производительность. О создании клонов я могу позаботиться сам, зато избегу ненужных расходов. Кстати, иногда в проектах встречаю подобное Код AS3:
Цитата:
BloodHound'а спросите, его детище. Я вообще использую в модели дисплей-объекты. |
Цитата:
|
Цитата:
Вам удобнее так, мне - иначе. Вот и весь сказ :) Цитата:
Однако, думаю, это защита от дурака. Т.е., например, первое распространение события еще не закончилось, а прогер уже задиспатчил эвент от того же объекта повторно. Допустим, без "пузырей". В итоге у события повисает фаза "цели". И когда поток исполнения программы возращается к баблингу первого события, уже имеется косяк: event.eventPhase === 2. Сомневаюсь, что такие мелочи проверяются перед каждым обработчиком. Цитата:
|
Ах, вот как! Следовательно. клонирование необходимо так же и для того, чтобы фазу на попортить.
А не напомните, где тот узкий участок был рассмотрен в темах? |
| Часовой пояс GMT +4, время: 07:59. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.