Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   запуск событий одного класса во множестве (http://www.flasher.ru/forum/showthread.php?t=175194)

in4core 12.02.2012 02:16

запуск событий одного класса во множестве
 
Не знаю как правильно назвать тему, извиняйте.

Давно мучает такой вопрос, есть у нас класс управляющий сервером, тоесть класс приемник данных от сервера и соотв диспатчит события при приходе определенных данных. Задача - подписываться на события из разных классов.
Самый простой вариант делаем класс статическим, создавая внутри диспатчер, и теперь из любой точки можно подписаться как
Код AS3:

StaticClass.addEventListener(...)

( естевенно addEventListener кастомный метод ). Так например на часть событий я могу подписаться в одном классе, а на часть в другом, или даже выписывать одни и теже события в разных классах выполняя различные методы.
Вариант два, так же статик, но передавать туда диспатчер типа
Код AS3:

StaticClass.dispatcher = internalDispacther;
internalDispatcher.addEventListener...
А в каждом новом классе internalDispatcher = StaticClass.dispatcher;

Этот самый вариант 2, видимо самый и убогий.
Но вариант 1, тоже не блещет, где то говорилось и обсуждалось , что статик в этом случае не есть тру.
Так вот интересно ваше мнение,
1. имеет право на жизнь статик в данном контексте ?
2. если не статик, то как ?
Архитектруа
Код AS3:

ServerClass
....
function onGetData(data) {  ???.dispatchEvent(...) }
//
SomeOtherClass
...
???.addEventListener(ServerClassEvents.SOME_EVENT... )
...
SomeOtherOtherClass и т.д.
 
???.addEventListener(ServerClassEvents.SOME_EVENT... )


Цветкофф 12.02.2012 02:28

написать класс, в котором будет единственная функция, она будет диспатчить события, а все остальные ваши классы наследуйте от написанного класса. Я бы так сделал, на мой взгляд данный вариант более логичен нежели вариант со статикой
ServerDispatcher.as
Код AS3:

package
{
        import flash.display.Sprite;
        import flash.events.Event;
 
        public class ServerDispatcher extends Sprite
        {       
                public function dispatcherServerEvent()
                {
                        dispatchEvent(new Event(ServerClassEvents.SOME_EVENT));
                }               
        }
}

SomeOtherClass.as
Код AS3:

package
{
        import flash.events.Event;
 
        public class SomeOtherClass extends ServerDispatcher
        {               
                public function SomeOtherClass()
                {
                        addEventListener(ServerClassEvents.SOME_EVENT,someFunction)
                }                       
                private function someFunction(e:Event):void
                {
 
                }
        }
}

SomeOtherOtherClass.as
Код AS3:

package
{
        import flash.events.Event;
 
        public class SomeOtherOtherClass extends ServerDispatcher
        {               
                public function SomeOtherOtherClass()
                {
                        addEventListener(ServerClassEvents.SOME_EVENT, someSomeFunction)
                }                       
                private function someSomeFunction(e:Event):void
                {
 
                }
        }
}

примерно как то так)))

Wolsh 12.02.2012 02:37

Обсервер?

Dukobpa3 12.02.2012 03:02

Та даже если уж в сторону статика смотреть то лучше синглтон крутить.
А так да, обсервер имхо лучший вариант. Хотя от синглтона мало отличаться будет в данном контексте. Но обсервер можно будет сделать не только для сервера а и вообще для рассылки чего-попало кому-попало. Тоже некая гибкость, хотя и контроллить сложно.

С обсервером получится асинхронная структура, с недостаточностью опыта может оказаться фатальным.

in4core 12.02.2012 03:42

Цитата:

Обсервер?
Ой как ужастно выглядет , вариант со статиком имхо в 500 раз выгоднее и приятнее читается, чем создавать такую жуткую конструкцию, тем более
Код AS3:

ExchangeRate.getInstance().registerObserver(this);

уже статика вообщем то

Wolsh 12.02.2012 12:13

Ахах) Ну ужас весь от интерфейсов, которые необходимы только потому, что в классической схеме не используются события, а идет прямое оповещение (просто вызов интерфейсного метода у подписчиков).
Цитата:

уже статика вообщем то
Наоборот, классический синглтон. Могло выглядеть и как
Код AS3:

Server.notifier.addListener(this);

Еще раз – если использовать готовую систему оповещений через события, то вопрос сводится к "статик или синглтон". Обсервер это альтернативный третий вариант. Я просто внес разнообразие в твой выбор. Хотя и так видно, что ты уже выбрал статик и размышляешь только о том, прятать диспатчер за статическим фасадом или выставить его в общий доступ. Если спрячешь, то получишь неясность с target/currentTarget (EventDispatcher не делегируется на Класс, только на интерфейс, а у Классов не может быть интерфейса))). Если это не пугает, то почему бы и нет. Прятать хорошо. Прятать "сервер" – тем более)) По крайней мере никакой злодей не заставит твой диспатчер разослать ложные сообщения.

Psycho Tiger 12.02.2012 12:28

Что-то ничего не ясно. EventDispatcher и есть Observer.

Wolsh 12.02.2012 13:29

Цитата:

EventDispatcher и есть Observer.
Ну не совсем. Обсервер предполагает наличие у подписчиков единого для всех метода, описанного в интерфейсе. Нотифаер тупо вызывает этот метод (при этом в базовой схеме никакого объекта вроде Event не отдается). Регистрируются не методы-обработчики, а сами экземпляры-подписчики. Их просто уведомляют, что нотифаер изменился, а они могут запросить данные по своим нуждам. EventDispatcher это конкретизированный обсервер, со своей специфической реализацией. То есть он – обсервер, но обсервер – не он.

Dukobpa3 12.02.2012 14:33

Цитата:

Сообщение от Psycho Tiger
Что-то ничего не ясно. EventDispatcher и есть Observer.

Ты уже во второй или третьей теме отстаиваешь эту идею.
Или в блоге каком-то, не помню.

И уже не первый раз тебе отвечают, что диспатчер это просто одна из частных реализаций обсервера. Но отнюдь не сферический обсервер в вакууме.

in4core 12.02.2012 14:40

Wolsh спасибо я тебя понял.

expl 12.02.2012 14:55

Цитата:

Цитата:
EventDispatcher и есть Observer.
Ну не совсем. Обсервер предполагает наличие у подписчиков единого для всех метода, описанного в интерфейсе. Нотифаер тупо вызывает этот метод (при этом в базовой схеме никакого объекта вроде Event не отдается). Регистрируются не методы-обработчики, а сами экземпляры-подписчики. Их просто уведомляют, что нотифаер изменился, а они могут запросить данные по своим нуждам. EventDispatcher это конкретизированный обсервер, со своей специфической реализацией. То есть он – обсервер, но обсервер – не он.
Это в Java нельзя передавать функцию - там так изголяются, а здесь ради чего? Никогда не понимал в этом отношении авторов PureMVC - слепить классический Observer и разбирать внутри типы событий switch-ами - вот кому они удобнее сделали? (хотя вариация без switch'ей этого фреймворка тоже ничего хорошего из себя не представляет - там другие проблемы на передний план вылазиют)

Dukobpa3 12.02.2012 15:04

Цитата:

Это в Java нельзя передавать функцию - там так изголяются, а здесь ради чего?
Это начало холивара события vs коллбеки? Или я чего-то не понял?

gloomyBrain 12.02.2012 15:05

Эмм... Мне одному кажется, что EventDispatcher - это нотифаер (IObservable)?

Dukobpa3 12.02.2012 15:06

Цитата:

EventDispatcher - это нотифаер (IObservable)?
Ну собственно так и есть, я так понимаю тут обсуждается схема в целом а не конкретные ее составляющие.

Wolsh 12.02.2012 15:15

В классическом обсервере нет ни событий, ни их типов соответственно. Все подписчики уведомляются без разбора при любом изменении нотифаера. Вызывается один и тот же метод у всех. Метод описан в интерфейсе, и все подписчики должны его реализовывать (одно из отличий от EventDispatcher, где регистрируются методы и вместо неприменимых здесь интерфейсов соблюдается "устная" договоренность о сигнатуре). Реализация соответственно разная, каждый запрашивает то что ему интересно. В этом избыточность – допустим подписчика интересует только изменение ширины, но он будет получать уведомление при всех изменениях: текста, высоты, цвета. Потом сделает запрос нотифаеру и узнает, что ширина таки не изменилась – ложная тревога.
На эту схему конечно можно нагородить и объекты данных типа событий, описать это в интерфейсе.. И желаемый тип изменений можно пририсовать в регистрацию, чтобы не гонять пустое.. Но базовое отличие от EventDispatcher именно в том, что регистрируются не методы а экземпляры, и соответственно требуется интерфейс подписчика, гарантирующий наличие метода для получения уведомлений.

expl 12.02.2012 15:39

Как-бы никто не спорит что реализации у него разные и классический сильно отличается от EventDispatcher, вопрос в том - зачем оно нам нужно.

Если вернуться к вопросу топика и перефразировать его в 2-х словах:
"Есть класс, дающий данные с сервера и он диспетчит события об их получении. Хочу отовсюду на них подписываться"

Тут обычно произносится фраза, за которую часто хочется ударить томиком "совершенный код" по рукам:
"А давайте сделаем этот класс синглтоном" (имеется в виду сам провайдер данных им сделать).
Но, на самом деле, можно и сделать - вряд ли вы так уж серьезно огребёте проблем с общедоступным провайдером данных. А можно и не делать - передавать провайдеры кому надо просто.

А статическим класс делать - как-бы нет причин, ну не замучаетесь Вы с написанием instance - провайдер данных - это не коллекция математических функций - к нему так часто не обращаются. А вот с проблем с невозможностью наследования, тестированием, а так же если второй экземпляр потребуется, или общий интерфейс для 2-х разных провайдеров - огребёте.

2 in4core: Или я чего-то не понял и кроме "подписаться отовсюду" есть ещё какие-то проблемы?

Dukobpa3 12.02.2012 15:52

Не вижу ничего страшного в синглтоне.

У меня в одном маленьком проекте (в большоих пока не пробовал такого) следующая схема:
Есть некий коннектор сервера - его дазача принимать и отправлять сообщения плюс конвертировать их в читабельный для флешки вормат.
Есть контроллер сервера который знает что делать с каждым сообщением, он там уже парсит и меняет модель.
А вот фишка вся в этой схеме в том что модель - синглтон:) Такое себе здаравенное дерево данных со своей структурой классов.

Есть пачка контроллеров, есть пачка вьюх. Когда контроллер инициализируется он вьюхи которыми рулит подписывает на какую-то из веток модели. И дальше всё типа вуаля.

Ну синглтоном мою модель назвать наверное неверно, так как модель действительно одна но к корневой модели доступ есть буквально у нескольких классов, куда-то глубже уже только ветки передаются.

Тоже как вариант.

Вообще идея оповещать какую-то кнопку что пришли данные с сервера слегка логически неверно как по мне. Эта кнопка о существовании сервера не должна догадываться, она должна видеть свою модель и просто отображать то что в ней.
И данную дискуссию как в в плане "посидим, поговорим" - да, но делать я бы так не стал. Ну может и стал бы, но постарался бы избежать.

expl 12.02.2012 16:03

Код AS3:

Не вижу ничего страшного в синглтоне.

Штука то удобная, но такая же удобная как копипаста - иногда лучше скопипастить, но если на этом построена половина проекта - он загнется через пару дней (трудность внесения изменений растёт как снежный ком - никакой гений не поборет).
Я имел счастье наблюдать 3 синглтона ссылающихся друг на друга (не считая кучи других, на которые они ссылались и которые ссылались на их) - там без поллитры было не разобраться кто кого дергает и когда кто инициализируется. А покрыть хотя бы один Unit-тестом - несбыточные мечтания. Хотя, если их мало - и сами синглтоны и классы, которые их используют вполне покрываются тестами, а те же "не синлтоны", ссылающиеся на половину приложения покрыть практически невозможно.

Цитата:

А вот фишка вся в этой схеме в том что модель - синглтон Такое себе здаравенное дерево данных со своей структурой классов.

Есть пачка контроллеров, есть пачка вьюх. Когда контроллер инициализируется он вьюхи которыми рулит подписывает на какую-то из веток модели. И дальше всё типа вуаля.
Ага, если их немного - то в коде вполне можно разобратся. Хотя на последнем проекте я отказался от корня модели - синглтона. Потому что появляется тенденция цепляться во вьюшке на что надо и не нато - ведь вся модель доступна со всех мест. Получалось, что изменение части модели, которое, казалось бы, не должно затрагивать именно эту вюьшку вполне ее затрагивает. Плюс тяжело использовать одну и ту же вьюшку с разными корневыми моделями (например в том же клоне фермы - в одном случае - корень - это сам пользователь, в другом - его друг, а вюьшка, вишь, на синглтон пользователя ссылается - и понеслись ветки if-ов в зависимости от глобального состояния игры).

Цитата:

Ну синглтоном мою модель назвать наверное неверно, так как модель действительно одна но к корневой модели доступ есть буквально у нескольких классов, куда-то глубже уже только ветки передаются.
Ну да, похожий подход и использую. Только модель обычно не одна - ведь надо еще и для друга создать - чтобы в гости хотидь, смотреть каких свиней 10-го уровня он выращивает.

Цитата:

Вообще идея оповещать какую-то кнопку что пришли данные с сервера слегка логически неверно как по мне. Эта кнопка о существовании сервера не должна догадываться, она должна видеть свою модель и просто отображать то что в ней.
И данную дискуссию как в в плане "посидим, поговорим" - да, но делать я бы так не стал. Ну может и стал бы, но постарался бы избежать.
Я так понял, у in4core сам класс, работающий с сервером выступает сам в качестве модели. Делали так на одной игре - впринципе работает, но очень тяжело временем получения данных с сервера управлять, что-то эмулировать на модели без сервера - не гибко, короче. Да, более гибкая модель - это:
- контроллер получает данные с сервера (когда ему другой контроллер скажет или какую-нть кнопку нажмут или еще по каким условиям)
- контроллер применяет полученные данные к модели
- а все остальные работают с моделью и слушают её.
Но может для задачи in4core это перебор и он решил интегрировать получение данных с сервера в модель - кто знает, тема топика вроде не про это.

Dukobpa3 12.02.2012 16:06

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

Добавлено через 19 минут
Цитата:

Ну да, похожий подход и использую. Только модель обычно не одна - ведь надо еще и для друга создать - чтобы в гости хотидь, смотреть каких свиней 10-го уровня он выращивает.
Ну у меня таки не синглтон. Просто одна модель. Без всяких там гетинстансов и прочего.
Мейн раздал всем кому позволено видеть ссылку на корень(мейнКонтроллер, серверКонтроллер, еще там что-то, не помню, но в общем объектов пять не больше).
Далее мейнКонтроллер уже раздает ссылки на ветки модели всем дочерним.

А насчет для друга для себя - это всё уже внутри этой большой модели.
Например большая модель, в ней:
- модель для статических данных с сервера
- модель для профиля друга
- модель для текущей игры
- прочее блаблабла.

Сама идея возникла именно из-за коммуникации с сервером. Контроллер сервера меняет модель и мы обходимся безо всяких обсерверов и прочей сомнительного качества лабуды и промежуточных явлений в виде маленьких контроллеров. Вьюхи сами видят изменения большой модели.

in4core 12.02.2012 16:37

Цитата:

2 in4core: Или я чего-то не понял и кроме "подписаться отовсюду" есть ещё какие-то проблемы?
Только подписаться отовсюду. Меня просто мучал вопрос, если делать не синглтон и не статику, а обычный экземплер созданный например в мейне. То как потом в других точках подписываться

Dukobpa3 12.02.2012 16:38

Другим точкам сервер не нужен. Моё мнение такое.

expl 12.02.2012 16:50

Цитата:

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

Т.е.: создал вюшку "морковь". Ты же ее не из ничего создал - была модель, которую создал контроллер, когда получил данные от сервера.
Скорее всего была главная вюшка, которая услышала собырие ADDED_ITEM(с полем "модель моркови"), которая создала вьюшку МОРКОВЬ, куда передала при создании модель моркови. И в следующий раз, когда сервер пришлет изменение степени зрелости этой моркови - контроллер найдет по айдишнику модель моркови в главной модели и поменяет параметр "зрелость", продиспетчится событие, которое услышит вьюшка и которая отобразит изменения. Т.е. вьюшка получила модель(провайдер изменений и данных) в момент создания. При этом контроллер серверный ничего и не знал о вьюшке.

Если данные об _изменении_ передавать в событии - есть некоторые проблемы - если вьюшка появилась после загрузки данных - она их не получит, поэтому этот случай не рассматриваю. Или именно так у тебя дела и обстоят?

GBee 12.02.2012 16:50

Передавать детям.

Добавлено через 4 минуты
Мне вообще непонятно о чем речь. Один большой класс, который работает с серваком и хранит все полученные данные и раздает их по запросу, посылая перед этим событие апдейта данных? Бррр.

Dukobpa3 12.02.2012 16:57

Цитата:

Мне вообще непонятно о чем речь. Один большой класс, который работает с серваком и хранит все полученные данные и раздает их по запросу, посылая перед этим событие апдейта данных? Бррр.
Да тут, по-моему, каждый о своем, вообще)

expl 12.02.2012 16:59

Цитата:

Мне вообще непонятно о чем речь. Один большой класс, который работает с серваком и хранит все полученные данные и раздает их по запросу, посылая перед этим событие апдейта данных? Бррр.
Скорее набор контроллеров, посылающих запросы серверу и разбирающих ответы. А данные хранятся не в контроллере а в древовидной модели, поэтому отдельные классы не такие уж и большие.

Но вообще да, тема куда-то уходит и начинает дублировать статью про "правильный MVC"

Dukobpa3 12.02.2012 17:05

На самом деле мне интересно тоже кто как взаимодействие с сервером организовывает?
Как выглядит одно сообщение?
Как оно обрабатывается клиентом?
Кем оно обрабатывается?
Что делать дальше с полученной от сервера информацией?

И в таком духе. Делитесь своими изобретениями и догадками.
Я про свое рассказал.
- Есть коннектор - внутри сокет-сервер, хттп-сервер, конфиги обрабатывает, может работать с разного рода серверами и выдавать не зависимо от этого сообщения в едином формате. Может принимать джейсон, может принимать АМФ, сейчас вот протобуф тестирую. Это всё здесь.
- Есть ДатаКонтроллер - получает отформатированное сообщение от коннектора, смотрит что пришло. Ну и ему глобально пофиг что там и с кем общается коннектор. Урлов он не знает, портов тоже, даже по какому протолу общение происходит тоже не вкурсе, ему пофигу хттп или сокет. Его задача только отправлять и получать сообщения во внутреннем формате в коннектор. Коннектор там разберется уже.
- А дальше в разных проектах по разному. В одном проекте вот как я выше написал - одна большая модель, которая подключена к ДатаКонтроллеру, датаКонтроллер напрямую меняет модель при получении сообщения. На ветки этой модели подписаны вьюшки, вьюшки не курсе о существовании большой модели, видят только свои маленькие которые внутри этой большой. В другом проекте есть обсервер, датаКонтроллер получает сообщение, спамит обсерверу оповещение мол так и так такие то данные изменились. Сами данные записывает в синглтон БД игры. К этому синглтону имеют доступ все кому не лень.

Как-то так. А как это выглядит у вас?

in4core 12.02.2012 17:37

ЧТобы не быть голословным вот более понятная архитектура , чтобы ясно было о чем речь ВСЕМ.

Код AS3:

private static const _nc                :NetConnection         = new NetConnection();
                private static const _sender        :Object                    = new Object();
                private static var _listener        :EventDispatcher;
 
                public static function connect(address:String , listener:EventDispatcher ):void {
 
                        _nc.connect(address);
                        _nc.client = _sender;
                        _listener = listener;
                        _sender.onSomeBack = onSomeBack;
 
                        _nc.addEventListener(NetStatusEvent.NET_STATUS, connectionStatus);
                }
 
                static private function onSomeBack(vars:*):void {
 
                        _listener.dispatchEvent( new C2SEvents(C2SEvents.SOME_EVENT , vars));
                }
 
                public static function disconnect():void {
                        _nc.close();
                }
 
                private static function connectionStatus(e:NetStatusEvent) :void {
 
                        const info : String = "NetConnection.Connect.Success" ;
 
                        if (e.info.code == info ) _listener.dispatchEvent( new C2SEvents(C2SEvents.CONNECT));       
                        else _listener.dispatchEvent( new C2SEvents(C2SEvents.DISCONNECT));
 
                }
 
                public static function callSomeMethod(var1:int, var2:int ):void {
 
                  _nc.call('serverMethod', new Responder(clinetMethod), var1, var2);
 
                }

Постарался именно архитектуру показать, поэтому заменил все слова.
Тоесть вот таких onSomeBack(vars:*) или callSomeMethod очень много соотв. Тоесть получили мы определенную пачку данных продиспатчили об этом нужным евентом. Почему встает такой вопрос, ну допустим :
1. Main тут мы создали и подключаемся, если подключение к серверу не прошло, просто не грузим библиотеки кликента и графику... ну нет смысла например )
2. Если соединение прошло, открываем некий ClassFrameWork где подписываемся на сообщения типа ( если это игра ) игра началась, игра закончилась и т.п.
3. Внутри же ClassFrameWork создается некий класс GameFrameWork где уже подписываемся на конкретные события игры - типа перс появился, перс умер и т.п.
П.с. конечно эти 3 пункта набросаны от башки и никто иак не делает, но я просто доношу смысл

GBee 12.02.2012 17:40

Цитата:

На самом деле мне интересно тоже кто как взаимодействие с сервером организовывает?
Меня один коллега подсадил на одну схему с которой я слезть не могу. И портирую, немного изменяя, от проекта к проекту.

Есть класс BaseOperation обертка над урллоадером со всеми обработчиками. В качестве параметра принимает урл, и два колбека (для результата и для ошибки). Шлет запрос, принимает ответ, если все хорошо - отдает в результатколбек ответ (хмл и джейсон) , плохо - ошибку в ошибкуколбек :о).

Если совсем плохо (невалидный хмл) падает :о)), но в отлаженном проекте такого нет.

Ну и дальше расширяющих классов пачка. Для каждого запроса.
GetUserListOperation
EditUserOperation
CreateProjectOperation

Каждый принимает как минимум два колбека + дополнительные парметры. В ответ отдает десериализированный объект или массив объектов. То есть в любой точке программы, могу получить нужную инфу от сервера. Если надо, то каждая операция может в статике кешить результаты и по запросу отдавать кеш. Короче мне нравится и удобно.

expl 12.02.2012 18:43

2 in4core:
Насколько понял, статический класс, который ты привел в качестве примера - это не "провайдер данных", как я думал, а просто класс, реализующий запросы к серверу.
Если отбросить инициализацию, забыть что класс статический и загнать диспетчер внутрь (вроде нет смысла передавать его снаружи) интерфейс бы выглядел так:
Код AS3:

/*
Диспетчит события
C2SEvents.CONNECT,
C2SEvents.DISCONNECT,
C2SEvents.SOME_EVENT
*/

public interface ServerAPI extends IEventDispatcher
{
    function callSomeMethod(var1:int, var2:int):void;
}

И ты обращаешься к этому классу в каких-то частях приложения, подписываешься на событие C2SEvents.SOME_EVENТ и вызываешь callMethod?
Можно еще раз объяснить "что не нравится" (просто я могу много чего рассказать, что мне не нравится в вашем примере со статикой, но это будет долго, а главное будет очень зависеть от контекста)?
Всмысле вот есть этот статический класс, что там мешает на него подписываться, или тебя раздражает, что он статический, или если бы он был не статический у тебя возникают другие проблемы, короче хочется услышать то же, что и в первом посте, только конкретнее.

in4core 12.02.2012 21:14

Цитата:

function callSomeMethod(var1:int, var2:int):void;
Это только заголовок, тоесьт таких методов сотни, и все их описать в интерфейсе бредово мне кажется.
Да раздражает фича Static.addEventListener , хотелось бы из любого места _dynamicClass.addEventListener

expl 12.02.2012 21:23

Если только это раздражает - сделай класс нестатическим и передавай всем кому надо
если тяжело передавать - сделай синглтоном. Вроде здесь проблем быть не может.
Вообще синглтон всегда гибше статик-класса - с ним можно больше вещей сделать. Просто у него чуть выше "overhead", т.е. Math.instance.cos(a) смотрелось бы дико (да и обращение бы дольше выполнялось). А здесь то:
Код AS3:

private var _dynamicClass:DynamicClass = DynamicClass.instance;

И погнал использовать внутри этого класса поле _dynamicClass.
Даже с тестами все в разы проще, чем со статиком, пример подмены класса на фейковый:
Код AS3:

private var _dynamicClass:DynamicClass;
public function ClassUnderTest(dynamicClass:DynamicClass = null)// конструктор
{
    _dynamicClass = dynamicClass != null ? dynamicClass : DynamicClass.instance;
}
 
// Использование в приложении
var instance:ClassUnderTest = new ClassUnderTest();
 
// Тестирование
var fake:FakeDynamicClass = new FakeDynamicClass();
var instance:ClassUnderTest = new ClassUnderTest(fake);
instance.method();
assertEquals("нужное значение", fake.field);

Пример реинициализации, если нужно протестировать сам синглтон (unit-тесты не должны зависеть от того что было раньше):
Код AS3:

// Использование в приложении
var instance:DynamicClass = DynamicClass.instance;
// Тестирование
var instance:DynamicClass = new DynamicClass();// А мы эксепшенов не кидаем :)
// Тестирование, если таки кидаем исключения в get instance:
var instance:DynamicClass = DynamicClass.instance;
instance.resetForTest();// Придется метод добавить, но кто говорил что синглтоны тестировать легко?

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

in4core 12.02.2012 21:24

Синглтон не люблю за констуркцию Class.getInstance() - меня это злит

expl 12.02.2012 22:27

Дык присвой полю это Class.getInstance() - чтобы код класса не засоряло.

А вообще, если тебя не злит:
- невозможность наследования;
- невозможность передать в качестве параметра;
- проблемы с тестированием;
- затрудненная инициализация класса (хотя с синглтонами не намного лучше);
используй статики на здоровье.

Как-бы я знаю только такие способы обеспечения доступа к объекту:
- сделать публичный статический метод/поле, возвращающий объект (синглтон сюда тоже относится)
- передавать объект в конструктор
- передавать объект в метод
- передавать объект в поле
- сделать сам класс публичным статическим (никаких объектов!)
- использовать IoC контейнер для автоматической передачи через конструктор/метод/поле
- создать событие "ДАЙТЕ МНЕ ПРОВАЙДЕР", сохранить в событии ссылку на клиента провайдера, послать баблингом вверх по цепочке, где-то вверху поймать, узнать клиента, присвоить полю клиента этот провайдер. Теперь у клиента есть ссылка на провайдер, хотя он понятия не имел где тот находится - ура :)

Ну что-то же из этого должно нравиться!?

in4core 12.02.2012 23:50

expl выше по коду вариант нормальный. учту


Часовой пояс GMT +4, время: 18:26.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.