![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
|
Помогите, не могу сообразить.
У меня есть кастом событие ServerEvent от которого наследуют другие ивенты ServerTableState, ServerPlayerAction, ServerBadCommand, etc. Поскольку от сервера приходят XMLи, а компоненты приложения работают с ивентами, я решил сбацать класс XML2Event, который бы получал на входе xml а возвращал бы кастомный ивент, который можно было бы далее диспатчить. public class XML2Event { public function XML2Event() { } // Какой класс должен быть в объявлении метода вместо Object, // учитывая, что возращаться могут разные ивенты? Object? public function parse(obj:Object):Object { var event:Object; var xml = new XML(obj); switch(xml.localName()) { case("server_state"): ... event = new ServerTableState(...); break; case("player_action"): ... event = new ServerPlayerAction(...); break; default: // bad command ... event = new ServerBadCommand(...); } return(event); } } И как правильно приводить созданные разные ивенты к типу возращаемого объекта? Т.е. как правильно написать метод, возвращающий объекты разных классов? |
|
|||||
|
Modus ponens
|
Switch - плохой подход, единственное оправдание использованию switch'a - это оптимизация на низком уровне (как правило при чтении и парсинге данных из потока и т.п.) в энтерпрайз switch противопоказан.
Если нет однозначности, что возвращать из функции - это плохой дизайн. Т.е. это значит, что функция выполняет более одной задачи, либо объекты неправильно типизированы. Такую ситуацию, как у вас можно разрулить например: private var typesTable:Object = { "foo": Foo, "bar": Bar }; private var callbacksTable:Object = { "foo": fooCallback, "bar": barCallback }; . . . function fooCallback(value:Foo):void { . . . } function barCallback(value:Bar):void { . . . } function createFromDefinition(type:String):void { callbacksTable[type](new this.typesTable[type]()); }
__________________
Hell is the possibility of sanity Последний раз редактировалось wvxvw; 28.02.2011 в 19:15. |
|
|||||
|
Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
|
Идея понятна, но как-то не полностью что-ли.
Из сокета приходят xml разной степени сложности. Надо где-то разместить код, который будет их рабирать, формировать структуры данных, которые нужно передавать дальше разным компонентам UI. Вы предлагаете где этот кусок расположить? вот, к примеру: Последний раз редактировалось zhoran; 28.02.2011 в 19:54. |
|
|||||
|
Modus ponens
|
Я бы делал так:
список классов-сообщений: MessageA, MessageB... MessageZ, все наследуются от Message у каждого есть метод clone(from:XML):Message который читает содержание из потока и создают свою копию исходя из полученных данных. Прийдется создать по экземпляру (лишнему) каждого сообщения, но, я не думаю, что это прям такая нагрузка, зато удобно. T.е. у вас будет таблица, например: private static const MESSAGES:Object = { messageA: new MessageA(), messageB: new MessageB() . . . }; private function parse(event:ProgressEvent):void { var messageXML:XML = XML(this._socket.readUTFBytes(this._socket.bytesAvailable)); var message:Message = (MESSAGES[messageXML.localName()] as Message).clone(messageXML); . . . }
__________________
Hell is the possibility of sanity |
|
|||||
|
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
вместо
можно использовать registerClassAlias и getClassByAlias
__________________
Отряд Котовскага |
|
|||||
|
Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
|
Интересная идея, возможно ли обойтись без объектов, что-то типа?
private static const MESSAGES:Object = { "messageA": MessageA, "messageB": MessageB . . . }; private function parse(event:ProgressEvent):void { var message:Message = (new MESSAGES[messageXML.localName()](messageXML) as Message); . . . } ![]() Добавлено через 3 минуты Ага, спс, но станет ли короче и понятнее? |
|
|||||
|
Цитата:
Цитата:
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Modus ponens
|
Наугад скопировал какой-то из 100500 свитчей в проекте который сейчас переделываю...
private function handleAPICalls(call:String, params:Array):void { var opponentData:UserData = VideoRoundData.getInstance().users.opponent; // MonsterDebugger.trace(call, params, MonsterDebugger.COLOR_ERROR); switch(call) { case ApplicationCallEnum.CLOSE_APPLICATION: killApp(); break; case ApplicationCallEnum.RESTART_APPLICATION: VideoRoundData.getInstance().managersBridge.inCallManager.runApp(VideoRoundData.getInstance().sessionData.curApplication); break; case ApplicationCallEnum.SEND_GIFT: var giftId:String = params[0]; var giftVo:GiftVo = VideoRoundData.getInstance().listsData.getActionVOById(ActionsEnum.GIFTS,giftId); if (opponentData) VideoRoundData.getInstance().managersBridge.inCallManager.sendGift(opponentData.userServerData.clientId, giftVo); else VideoRoundData.getInstance().managersBridge.inCallManager.sendGift(null, giftVo); break; case ApplicationCallEnum.CHANGE_EFFECT: var effectId:String = params[0]; var effectVo:EffectVo = VideoRoundData.getInstance().listsData.getActionVOById(ActionsEnum.EFFECTS,effectId); if(opponentData) VideoRoundData.getInstance().managersBridge.inCallManager.setEffect(opponentData.userServerData.clientId, effectVo); else VideoRoundData.getInstance().managersBridge.inCallManager.setEffect(null, effectVo); break; case ApplicationCallEnum.CHANGE_SKIN: var skinId:String = params[0]; var skinVo:SkinVo = VideoRoundData.getInstance().listsData.getActionVOById(ActionsEnum.SKINS,skinId); if (opponentData) VideoRoundData.getInstance().managersBridge.inCallManager.setSkin(opponentData.userServerData.clientId, skinVo); else VideoRoundData.getInstance().managersBridge.inCallManager.setSkin(null, skinVo); break; case ApplicationCallEnum.GET_PARTICIPANTS: var clientId :String = VideoRoundData.getInstance().users.client.userServerData.clientId; var opponentId :String = (opponentData != null)? opponentData.userServerData.clientId : ""; callApplication(ApplicationCallEnum.GET_PARTICIPANTS_CALLBACK, clientId+","+opponentId); //_____Shooters if (opponentData) { var userDataParam:String = VideoRoundData.getInstance().users.client.userServerData.name + "," + VideoRoundData.getInstance().users.client.userServerData.photo + "," + VideoRoundData.getInstance().users.opponent.userServerData.name + "," + VideoRoundData.getInstance().users.opponent.userServerData.photo; } else { userDataParam = VideoRoundData.getInstance().users.client.userServerData.name + "," + VideoRoundData.getInstance().users.client.userServerData.photo + "," + VideoRoundData.getInstance().users.client.userServerData.name + "," + VideoRoundData.getInstance().users.client.userServerData.photo; } callApplication("remoteSetClientsParams", userDataParam); break; case ApplicationCallEnum.GET_SKINS: callApplication(ApplicationCallEnum.GET_SKINS_CALLBACK, constructShortVoList("skins")); break; case ApplicationCallEnum.GET_EFFECTS: callApplication(ApplicationCallEnum.GET_EFFECTS_CALLBACK, constructShortVoList("effects")); break; case ApplicationCallEnum.GET_GIFTS: callApplication(ApplicationCallEnum.GET_GIFTS_CALLBACK, constructShortVoList("gifts")); break; case ApplicationCallEnum.SEND_MESSAGE: var message:String = params[0]; if(opponentData) VRViewEventDispatcher.getInstance().dispatchEvent(new VRViewEvent(VRViewEvent.SEND_CHAT_MESSAGE, message)); break; } } >Интересная идея, возможно ли обойтись без объектов, что-то типа? Конструктор нельзя параметризовать. Т.е. вы в таком случае не застрахованы от ошибки (можно что-то не то передать в конструктор, и компилятор это не проверит). А так - конечно можно.
__________________
Hell is the possibility of sanity Последний раз редактировалось wvxvw; 28.02.2011 в 20:52. |
|
|||||
|
.
|
Цитата:
А вот мне сразу не понравились эти ServerEvent. Я стараюсь проектировать приложение так, чтобы не зависеть от источника данных. Чего и Вам советую. Последний раз редактировалось dimarik; 28.02.2011 в 21:06. |
|
|||||
|
Регистрация: Dec 2010
Адрес: Химки МО
Сообщений: 95
|
Не зависеть это хорошо, но не понятно что Вы имеете в виду в контексте ServerEvent.
|
![]() |
![]() |
Часовой пояс GMT +4, время: 02:55. |
|
|
« Предыдущая тема | Следующая тема » |
|
|