Форум 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=206060)

GBee 16.01.2014 15:15

Цитата:

когда ты делаешь запрос, в ответе ты должен получать command:What_the_fox_say
У вас же есть ссылка на соответствующий стандарт?

Dukobpa3 16.01.2014 17:11

Цитата:

как с точки зрения пользовательского кода выглядит хорошая на твой взгляд система?
Ну так примерно набросал. Просто внутренности не стал показывать, в виду костыльности.
Ну и после наведения порядка внутри - АПИ тоже может как-то поменяться. (Статик манагер тоже под вопросом, но вот так вот вслепую не могу точно сказать. Надо смотреть на интеграцию в систему. Пальцем в небо сложно.)
Код AS3:

CommandManager.executeCommand(CommandList.COMMAND_AUTH);

Код AS3:

var turnDto:BattleTurnDto = new BattleTurnDto();
turnDto.battle_id = "1";
turnDto.unit_id = "10";
CommandManager.executeCommand(CommandList.COMMAND_BATTLE_TURN, turnDto);

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

Тут сам по себе подход сервера убог
Не убог. Обычная себе синхронная система. Просто я привык к асинхрону и stateless, потому такое не люблю. Но подход нормальный сам по себе.

Psycho Tiger 16.01.2014 18:53

Ну гм, тогда я тебя не понимаю.
Сожмём твой код:
Код AS3:

var turnDto:BattleTurnDto = new BattleTurnDto();
turnDto.battle_id = "1";
turnDto.unit_id = "10";
CommandManager.executeCommand(CommandList.COMMAND_BATTLE_TURN, turnDto);

Внесём в конструктор то, что ты вставляешь сеттерами (филдами?).
Код AS3:

var turnDto:BattleTurnDto = new BattleTurnDto(1, 10);
CommandManager.executeCommand(CommandList.COMMAND_BATTLE_TURN, turnDto);

У нас обоих в наших реализациях один запрос – одна команда. Поэтому я вышвыриваю CommandList.COMMAND_BATTLE_TURN из этого кода, внося её в конструктор BattleTurnDto. Зачем? Это DRY. Типа
Код AS3:

public function BattleTurnDto(battleID:int, unitID:int){
super();
super.commandName = CommandList.COMMAND_BATTLE_TURN;
}

Поэтому код сжался вот так:
Код AS3:

var turnDto:BattleTurnDto = new BattleTurnDto(1, 10);
CommandManager.executeCommand(turnDto);

Теперь я прикидываю, что всегда создавая команду я буду её отправлять. Через CommandManager. Это опять же значит, что я могу создать метод execute() внутри BaseCommand, который будет исполнять вот эту строчку:
Код AS3:

CommandManager.executeCommand(turnDto);

(в реальном коде это будет выглядеть как-то так)
Код AS3:

public function execute():void{
CommandManager.executeCommand(super.commandName, this);
}

Ну и, конечно, после её исполнения надо где-то обработать ответ. Обычно я делаю это внутри самой команды: она сама находит нужные модели, расфасовывает данные и прочее, но иногда удобно получить коллбек о том, что команда исполнена в пользовательском коде. Добавляется листенер addCompleteHandler.
Вот так рождается строчка:
Код AS3:

new BattleTurnDto().executeCommand().addCompleteListener(completeHandler);

На каком шаге это сжатие кода превращает примерно-нормальный в код Александра?

Dukobpa3 17.01.2014 03:47

Цитата:

Внесём в конструктор то, что ты вставляешь сеттерами (филдами?).
Согласен. Не стал делать в угоду универсальности, а могут быть структурки набором полей поболее двух, тогда конструктор будет унылым.

Цитата:

У нас обоих в наших реализациях один запрос – одна команда. Поэтому я вышвыриваю CommandList.COMMAND_BATTLE_TURN из этого кода, внося её в конструктор BattleTurnDto.
А вот здесь фейл, потому что эту структуру может слать несколько команд.
Или же одна команда может слать разные структуры(Это уже плохой вариант, но мало ли).
Но в любом случае нигде не было оговорено связи структура == команда, ты искусственно эту связь прикрутил.

Цитата:

Поэтому код сжался вот так:
См выше. Если не фейлить - то не сожмется.

Цитата:

Теперь я прикидываю, что всегда создавая команду я буду её отправлять. Через CommandManager. Это опять же значит, что я могу создать метод execute() внутри BaseCommand, который будет исполнять вот эту строчку:
Код AS3:

CommandManager.executeCommand(turnDto);


Рассуждения верные, выводы не очень.
Сразу же вопрос - а зачем было добавлять манагер с таким подходом?
Как бы изначально екзекьют и есть в команде. Его наружу проксит манагер, ты берешь обратно заворачиваешь екзекьют через манагер в команде? О_о Логику совсем не уловил. Убери манагер и будет счастье.

Дальше всё строится на этом твоем примере потому чем дальше тем глубже.

Проще сделать таким вот образом, если сильно хочется:
Код AS3:

new BattleTurnCommand().execute(new BattleTurnDto(1, 10));

И тогда никакой манагер тебе никуда не упирается (а он в твоей логике таки никуда не упирается, всеми своими доводами ты от него избавиться пытаешься)

//****************************
И я предпочитаю single responsibility.
структурки - тупо типизация чтоб обжекты не гонять.
Команда - команда, ничего более. Разве что благодаря тому что она асинхронная и ждет ответа - в нее инкапсулировали еще и обработку данных.
Менеджер - не знает чем занимаются команды. Просто холдер. В его задачи входит убивать отработавшие команды или наоборот оставлять список созданных команд, чтоб не пересоздавать. Это уже от желаемой логики зависит, как там системе удобнее будет.

Psycho Tiger 17.01.2014 10:47

Цитата:

И тогда никакой манагер тебе никуда не упирается (а он в твоей логике таки никуда не упирается, всеми своими доводами ты от него избавиться пытаешься)
У меня его и нет. Я его "образно" туда всунул, чтобы поближе к твоему примеру. Мои команды - эдакие микро-контроллеры, сами всё знают и умеют.

Я понял, где у нас расходятся мысли. В моём подходе – одна структура-одна команда в обоих направлениях.
То есть, например есть 3 команды: "Добавить в друзья", "Посмотреть профиль", "Пригласить в мой клан" – и все 3 команды отсылают на сервер одну и ту же структуру – маленькую такую, в одное поле – user_id. В твоём случае – ты хочешь действительно слать одну и ту же структуру (дто), а вот я как раз это и считаю фейлом.
Почему? Потому что это попытка агрегации кода, который агрегирован быть не должен. Если есть константа "4", указывающая на версию протокола и константа "4", показывающая максимальное количество одетых колец – то они как бы равны, но это не значит, что они как-то связаны.
Так и в твоём случае твой подход тебя подведёт, когда при добавлении друга добавиться возможность уведомить его (лишний флаг notice, который не нужен в других двух командах), а при приглашении в клан указывать, какого из типов (клан рабочих/пользовательская гильдия/да всё что угодно). Создание новых Dto, расползание их внутри команд. Это не большая проблема в силу Find Usages в IDE, но я нахожу это неудобным. Поэтому я живу счастливо, интегрируя дто внутрь команды. Такие дела.
Цитата:

И я предпочитаю single responsibility.
По мне, с этим есть проблемы. Вообще, SR говорит что "Один класс – одна обязанность" и в целом, ничего более. Ключевое слово здесь класс: любой класс можно разбить на множество других, каждый из которых будет SR. То есть, если я "вошью" поля из дто прямо в команду – то да, SR может нарушиться. Но если я вошью их в, уже по сути лишнюю сущность дто и уже её вставлю как поле команды – SR будет на месте, но загрустит Оккама.

Dukobpa3 17.01.2014 15:09

Цитата:

"Добавить в друзья", "Посмотреть профиль", "Пригласить в мой клан" – и все 3 команды отсылают на сервер одну и ту же структуру – маленькую такую, в одное поле – user_id.
Да, но только не структурка "user_id", а что-то типа: user_params.user_id.
И если вдруг появятся user_params_for_invite отдельно от других - появится еще одна структурка. Но не раньше. Потому что велика вероятность что она и не появится. И вот тут вот имеет смысл включать твоего оккама:)

Возьми вот это:
Цитата:

Код AS3:

new BattleTurnDto().executeCommand().addCompleteListener(completeHandler);


- Убери из него new, так как каждый раз создавать новую структуру и не следить за ней не ок. Я предполагаю что она в каком-то буфере/холдере/манагере, который либо удалит, либо очистит, либо закеширует после выполнения.
- Сделай так чтоб стартовало не со структуры, а с команды. Потому что по логике ты вызываешь якобы команду, а не данные. И не команду для данных. А В КОМАНДЕ ШЛЕШЬ ДАННЫЕ. Незачем добавлять непонятностей и неочевидностей в код.
- комплит листенер - то с чего начинал ТС. То от чего я пытался уйти. Хочешь вернуть обратно - верни.

получится:
Код AS3:

_battleTurnCommand.execute(1, 10).addCompleteListener(completeHandler);

И в этом месте наши мнения сойдутся.

//**********
И я за то что если уж ООП, то лишней ненужной абстрактности добавлять незачем если для этого нет доп-мотивации. Стараюсь объекты соотносить с реальными объектами "из жизни". С логическими сущностями.

Psycho Tiger 18.01.2014 10:41

Цитата:

- Убери из него new, так как каждый раз создавать новую структуру и не следить за ней не ок. Я предполагаю что она в каком-то буфере/холдере/манагере, который либо удалит, либо очистит, либо закеширует после выполнения.
Ну, конечно. BattleTurn.getInstance(), Pool.getInstance(BattleTurn), new BattleTurn – это всё не так важно в этом конкретном примере. Я стараюсь визуально облегчить примеры для форума.
Цитата:

- Сделай так чтоб стартовало не со структуры, а с команды. Потому что по логике ты вызываешь якобы команду, а не данные. И не команду для данных. А В КОМАНДЕ ШЛЕШЬ ДАННЫЕ. Незачем добавлять непонятностей и неочевидностей в код.
Ага, я упоминал в чате, что я Dto сначала не так понял – расценил как часть имени команды. Конечно, создается команда.
Цитата:

- комплит листенер - то с чего начинал ТС. То от чего я пытался уйти. Хочешь вернуть обратно - верни.
Тебя в них смущает, я так понимаю, исключительно вопрос GC / конвенции.
С коллбеками – если положить их в Dictionary с weakKeys, то даже с повисшим коллбеком не будет проблем. Но откуда он может повиснуть, если при всех ошибках этот коллбек тщательно чиститься ?
Что касается конвенции – можно подписываться Event'ом, опять же с weakKey. Опять же, не смотри на addCompleteListener как какую-то законченную идею: это может быть и сигнал, и эвент. Конкретней рассматривается уже в контексте разрабатываемого приложения.

Zebestov 18.01.2014 12:04

Может я сейчас что-то не то скажу, но кто мешает пользоваться обычным URLLoader и словарем, где ключ — наш лоадер, а значение — необходимая идентификация пришедшего COMPLETE, например "вот это он ответил с какого он раёна", "а вот это он ответил почему такой дерзкий".

fljot 18.01.2014 15:29

Цитата:

Сообщение от Psycho Tiger (Сообщение 1157628)
С коллбеками – если положить их в Dictionary с weakKeys, то даже с повисшим коллбеком не будет проблем.

оффтоп, но будь осторожен http://gskinner.com/blog/archives/20...ctionary_.html

Цитата:

Note that there is a known bug with Dictionary that prevents it from operating correctly with references to methods. It seems that Dictionary does not resolve the method reference properly, and uses the closure object (ie. the “behind the scenes” object that facilitates method closure by maintaining a reference back to the method and its scope) instead of the function as the key. This causes two problems: the reference is immediately available for collection in a weak Dictionary (because while the method is still referenced, the closure object is not), and it can create duplicate entries if you add the same method twice. This can cause some big problems for things like doLater queues.

Zebestov 18.01.2014 15:41

Оу. Надо же, последний камент от Psycho Tiger невнимательно прочел )) он о том же.


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

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