![]() |
Должен ли вид быть IEventDispatcher'ом?
Мы тут недавно поспорили по этому поводу, но, хотелось бы услышать еще мнения.
Я думаю, что нет, другая сторона думаeт, что да. Мои доводы: Примеры классы Graphics и BitmapData, которые вполне подпадают под описание "вида" по моему мнению. + другие "самодельные" виды, типа как например управление HTML элементами страницы, или запись файла, который тоже может быть видом для другого приложения. (Все, опять же только мое мнение). Доводы другой стороны: Флеш на 99% рассчитан на работу с дисплей объектами, и подписываться на события от них - это как бы в порядке вещей, и вообще удобно. + возможность диспатчить в них события типа "бродакаст" делает подход к проблеме несколько более универсальным. + одинаковый подход к работе с видом, т.как любой вид можно представить, как один и тот же интерфейс, не вдаваясь в конкретику. + это несколько упрощает планирование. Так, например, если апдейты во вью не моментальные, то мы легко решаем проблему асинхронности апдейтов. Вобщем, хотелось бы услышать ваши мнения. |
Мне кажется, что, если мы говорим всё-таки о флеше, то здесь как минимум 90% видов наследуют от класса, реализующего этот интерфейс. Поэтому поводом к неиспользованию IEventDispatcher могут стать только существенные недостатки, которые это использование за собой повлечёт. Какие преимущества даёт использование этого интерфейса, вы только что подробно рассказали :) Серьёзных недостатков я не вижу. Да, идеологически немного неправильно, но только немного, и проявляться это будет нечасто. Так что, думаю, должен (вернее, стоит).
|
Я думаю да, конечно.
Любой вид должен имплементить этот интерфейс Цитата:
|
не соглашусь что BitmapData подпадает под описание "вида". это объект с данными, о чем нам и сигнализирует суффикс Data.
Graphics же - просто интерфейс (тоже не "вид") |
я не думаю что это критично (Должен ли вид быть IEventDispatcher'ом), так как вид главным образом должен служить для отображения данных и если от него не требуется обратной связи (например регистрация действий пользователя) то нафига спрашивается ему быть диспатчером?
wvxvw, я за тебя :) |
Просто когда мы это примеряем на флеш, то нам подход с дисплей объектами кажется очевидным, но, флеш это все таки не единственое место, где MVC имеет место быть :), в том же PHP существует точно такая же парадигма, и там как-то никто не предполагает, что вид будет дисатчить события обратно... Как правило предполагается в него просто сеттить чего-нибудь.
Да, может быть Graphics не самый удачный пример, птотому что он не расширяемый, а вот BitmapData вполне, как на мой взгляд может выступать в качестве вида - банальный пример: Рисуем графику в битмапдату и передаем ее серверу на сохранение. В этом случае нашим видом будет битмапдата... Как бы интерфейс он же не обязан быть с пользователем, он может быть и с другой программой. |
А через что кроме вида можно получать события от пользователя? Лишив вид возможности рассылать события, мы лишаем приложение всякой интерактивности.
Если же вид является просто отображением, а не интерфейсом, то тогда он вполне может обойтись без рассылки событий. |
GAIKER верно высказался, я тоже не совсем понял идею лишать вид диспетчеризации.
А броадкастинг очень плохая затея. Пользуясь броадкастингом можно запутать все связи между составляющими. Каждый объект должен знать свое место и не знать ничего о тех к кому он не имеет отношения. |
wvxvw, что-то не вяжется твоя теория о том, что BitmapData - это представление. в твоей схеме представлением является сервер :) контроллер заполнил модель ( BitmapData ) и отдал представлению ( сервер ).
а по поводу IEventDispatcher... необязательно представление должно его реализовывать. просто в АС3 у тебя не получится иначе :) зато в том же пыхе, у тебя это получается. хотя если результатом работы скрипта является HTML, то в итоге ты получишь IEventDispatcher только браузеровский. IEventDispatcher нужен только в том случаи, если контроллеру нужен callback от представления. хотя некоторые евангелисты предпочитают использовать функции-свойства вместо событий, типа быстрее и круче. |
Ну битмапдата, имелась в виду, например, такая ситуация:
У нас есть русунок, есть его представление в векторном виде - это бишь модель. И есть его представление в виде пиксельной картинки. Эта картинка вообще не является частью интерфейса, например, карта, куда пользователь кликал за время пребывания на сайте. С точки зрения сервера картинку можно рассматривать как модель, но на клиенте это все таки будет вид ИМО. И это я не против наличия свойств диспетчера в виде, я против того, чтобы, например контроллер вcегда предполагал, что вид является диспатчером. Т.е. должен ли контроллер: Код:
// достаточно ли делать так |
Цитата:
Цитата:
|
Цитата:
В данном случае скорее логично что представление получило событие от модели, обновилось и само послало об этом событие. |
Цитата:
А каким образом по вашему происходят т.н. broadcast type events? Ну, например, Event.ADDED_TO_STAGE, Event.ENTER_FRAME и тому подобные? Или вы каким-то образом подпишитесь в виде (он же, пусть Sprite) на события от контроллера (он же Stage) до получения ссылки на контроллер? Как позвольте спросить? |
wvxvw, это механика работы плеера, сам программер получает событие от самого чилда.
Но вот принудительно вызывать методы типа update и слать события извне — не комильфо. У нас, например, вообще снаружи отправлять события нельзя. |
обычно у меня происходит нечто вроде этого:
Код AS3:
|
Для многопоточной среды ваш спор имел бы смысл, но не принципиальный. Можно так, можно этак, договоримся. Если и не договоримся, плевать, я лично долго не спорил бы)). Там хоть есть, о чем поговорить.
Плеер - однопоточная среда, все эти игрища с эвентами - сплошное запудривание мозга. Диспатчить чужие события не хорошо, твой аргумент это подтверждение/следствие опять же однопоточности. Точнее, эти эвенты как раз и завязаны на общий поток исполнения. В частности, я не понял, как наличие диспатчера в представлении поможет решить проблему асинхронности апдейта. Нет, ну можно поговорить о распределенных приложениях с участим плеера, типа клинет-сервер, несколько флэшек на странице, оболочка. В этом случае сервер/другая флэшка/оболочка -часть общей архитектуры приложения, и в таких системах чаще плеер сам как вид)). |
а однопоточная ли плеер среда? работал с Socket и наткнулся на то что иногда приходит новый пакет пока еще обрабатывается старый и параллельно начинает обрабатываться..
не исключено правда, что я где-то накосячил.. но все таки у меня появилось ощущение многопоточности плеера.. |
AS код - однопоточен, но внешние операции (прорисовка, загрузка внешних данных, слушание мыши и пр..) Может и идут в других потоках. Хотя не факт.
|
Цитата:
Цитата:
И как бы события они скорее следствие того, что плеер, как програма - многопоточный, а язык не предусматривает такой возможности ИМО. |
Объект диспатчит событие, когда хочет сообщить о чем-то, что произошло с ним или внутри него. Это понятно, логично и правильно.
А вот когда кто-то начинает управлять отсылкой событий через подставное лицо, сразу возникает куча вопросов. И первый из них - если что-то произошло в объекте А, то почему вдруг я узнаю это от Б? |
Тоесть пример с ентерфреймом вас не убедил? :)
Ну хорошо, такой пример: У нас есть соединение с сервером, которое посылает команды клиенту. Мы можем использовать следующие подходы: Самый простой: У класса соединения определяем все методы, которые можно вызвать. - Недостатки, соответственно, отсутствие гибкости, возможно куча методов, многие из которых не будут вызываться никогда в некоторых сценариях и т.д. У класса соединения есть свойство client и этот объект уже должен реализовывать методы, которые мы собираемся вызывать через удаленную процедуру. - Недостатки: нужно создавать какие-то служебные объекты и, почти наверняка некоторые методы прийдется реализовывать в каждом из клиентов, или создавать целую иерархию таких клиентов с абстрактными классами... вобщем, мрак и куча лишнего кода... Мы можем создать универсальный обработчик, в который мы будем передавать название или ссылку на нужный нам метод клиента + аргументы и надеятся на то, что обработчик их вызовет через отражение или еще как. - Недостатки: клиент может не обработать сообщение вообще. Изначально предполагается, что ссылку на класс "раздающий указания" мы не хотим или не можем по техническим причинам передать в классы которые слушают / выполняют указания. Потому что, например, получение такой ссылки повлечет за собой создание ненужных зависимостей. Пример: Stage попадает в список зависимостей DisplayObject потому, что у DisplayObject есть свойство stage, но мы бы могли это избежать просто работая с событиями, которые нам stage диспатчил бы от имени получателя (таким образом не давая ссылку на самого себя). |
Что-то я не пойму твою мысль..
Значит, нам приспичило иметь объект А, который может диспатчить события, но от имени другого объекта В. Так. Хоршо. Этот другой объект В ничего не знает и не дожен знать о существовании объекта А. Так. Мы имеем таким образом, независимый от А В. Так. Тогда А получается зависимым от В, ибо нужна ссыль чтоб диспатчить. Так. Не понял. По-другому. Имеем В, который диспатчит эвент. Так. Имеем А, которму пофик на всех. Так. Но, что бы получить эвент, надо подписаться, значит А должен иметь ссыль на В. Стало быть А, будь он сторонним рассыльщиком, или просто листенером должен иметь ссыль на В. Не понял. Хорошо. Пусть есть С, который хочет получать эвенты от А. Но мы хитро диспатчим через В, ибо не хотим, чтобы С, знал про А. Так. Тогда имеем С с сылкой на В, и А с сылкой на В. С и А ничего не знают друг о друге. Так. Но А, тем не менее шлет эвенты С, правда С получает их от имени В, но тем не менее. Круто. Так что ли? А в чем должен был убедить пример с энтерфреймом? В том что так бывает, и даже неплохо работает? значит А - это стейдж, В - это объект, у которого А "поддиспатчивает" энтерфрейм. Так. Значит, мы можем иметь С, который получает энтерфрейм от стейджа, и который о стейдже ничего не знает. Так что ли? |
wvxvw, что в примере с энтерфрэймом могло меня убедить, и в чём?
я вообще не понимаю твои примеры. как в анекдоте: Цитата:
Код AS3:
и с передачей всех дисплэйобджектов бродкастеру, ссылок там ещё больше получается. |
alexcon314:
Да, практически так. Но немного запутано... Есть А и Б, А создал Б и после его создания проделал еще какие-то свои операции и продиспатчил в Б собыия сигнализирующие о том, что эти операции были сделаны. пример: DispalyObjectContainer#addChild(child); Наши варианты действий: Мы можем у child вызвать метод onAdded() а можем проверить а не подписался ли child на "onAdded" и только в случае если подписался вызвать onAdded() о сыществовании которого мы можем до этого и не знать вообще. Второй вариант экономичнее и не обязывает child имплементить onAdded в обязательном порядке. На это накладывается еще такой момент: мы не хотим позволять ребенку знать больше чем положено о его родителе, т.как не хотим давать ему какие-либо полномочия по управлению родителем. По этому мы продиспатчим в него событие от имени ребенка, ну или не важно, пусть даже target будет null, главное ссылку на родителя не давать. Если вы задумаетесь о таком подходе к, например, stage - то это бы разом решило кучу непоняток с песочницами, неудаляемым загруженым контентом и т.п. Т.как в таком случае у ребенка не было бы ссылки на stage, и он бы не смог создать жесткие ссылки туда, куда ему лезть не разрешено... BlooDHounD: Я почему-то думаю, что там схема такая же, как и в IE6 (window.event). Т.е. имеется какой-то глобальный броадкастер к которому мы подписываемся когда подписываемся на тот же ентерфрейм. Почему я так думаю - потому что mx EventDispatcher был именно так организован, и я сомневаюсь, что схему переделали. И этот самый глобальный броадкастер именно диспатчит события от имени подписчика. Иначе мне тяжело представить, каким образом ентерфрейм наступал бы синхронно везде, да и вообще, откуда бы клип узнал, что ему нужно продиспатчить ентерфрейм? ЗЫ. Анекдот был в оригинале про летчиков :) |
Цитата:
|
wvxvw, не представляешь? так я же код написал ) событие срабатывает у всех синхронно согласно моему коду. есть глобальный диспатчер, который является статическим экземпляром ( _BROADCASTER ). при этом писать супер навороченный функционал по обработки ВСЕХ дисплэйобджектов не нужно. даже не нужно собирать их в коллекцию. достаточно подписать на событие у этого брадскасера и послать его от своего имени. в твоём же случаи надо написать тонну кода, который работает медленнее, так как он пробегает ВСЕХ детей и проверяет, а есть ли у них слушатели? в моей схеме в коллекции собираются только объекты, у которых есть слушатели. и собираются они готовым функционалом EventDispatcher'а, что с точки зрения здравого смысла и экономичнее и быстрее, а с точки зрения ООП, ваще идеально вписывается ( переиспользование инкапсулированного класса ).
твой пример с addChild мне опять не понятен. если ребёнку не нужно знать, что его добавили куда-то, то зачем в вообще заморачиваться с onAdded? и скорее всего не вызывается в плэйере такого метода. как мне кажется там вызывается метод Код AS3:
события диспатчатся от имени child, почему о них должен заботится родитель? не понятно. так же непонятно, зачем родителю совершать ненужные и идиотские проверки, если ребёнок не должен диспатчить это событие ни в коем случаи? в моей схеме понятно. отнаследовались и переопределили setParent. а в твоей? закидываем дрожжей в родительский класс и начинаем плодить switch/case на каждое особенное поведение ребёнка в одном методе? и самое обидное, что этот код вообще может не понадобится, так как я не использую никого кроме одного конкретного ребёнка. зато всt логические деревья детей вкомпилятся в приложение в обязательном порядке, так как поведение детей описывается в классе, в котором вписан switch и 15 case, в которых надо информация о идентификации детей. резюме: повторяю в 3й раз, что то, что ты описываешь ни коем образом не касается имплементации EventDispatcher. это вопрос из области "а использовать ли мне ООП"? |
Blood, твой код не отражает действительность - таргет события полученого в обработчике ентерфрейма не будет == _BROADCASTER... я не спорю о достоинствах такой схемы, просто в реальности она так не работает.
Как раз если бы ты прочитал внимательнее, ты бы понял, что никакого switch-case не предвидится. Есть набор предопределенных событий которые может продиспатчить родитель. И тип ребенка не влияет на логику - главное, чтобы ребенок был IEventDispatcher. По поводу: Код AS3:
|
кароче. ты видишь то, что хочешь видеть и чёрти знает что придумываешь. да, target !== _BROADCASTER, так как именно это нам и надо! ты вот сейчас о чём? нам же надо что бы таргет был child.
что касается всего остально, я уже описал в чём минусы схемы. она не ООП. то есть она не расширяема. наважно, что у тебя там будет. этот вопрос вообще не относится к событиям это вопрос архитектуры. если не понимаешь, то забудь. у тебя вопрос не правильно задан. Цитата:
Цитата:
Код AS3:
|
вот как может выглядить код в базовом EventDispather
Код AS3:
|
Котяра, чем Ваш код отличается от моего? не считая дополнительных телодвижений, и дополнительной функции?
|
Цитата:
Если отличий мало, значит это что-то да значит) а дополнительная ф-ция равна super.dispatchEvent в вашей реализации |
| Часовой пояс GMT +4, время: 12:12. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.