Должны ли отдельные классы прислушиваться к глобальным событиям или вместо них «менеджер» обновляет их? - PullRequest
1 голос
/ 21 ноября 2011

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

, например:

import App
public class DualLanguageText
{
    public function DualLanguageText():void
    {
        App.Model.addEventListener(AppEvent.CHANGE_LANGUAGE, onChangeLanguage)
    }
}

... или

import App
public class ViewManager
{
    public function viewManager():void
    {
         //Create Text Components
         App.Model.addEventListener(AppEvent.CHANGE_LANGUAGE, onChangeLanguage)
    }

    private function onChangeLanguage(e:AppEvent):void
    {
         for each (var dtext:DualLanguageText in _textComponents)
         {
             dText.changeLanguage(e.id);
         }
    } 


}

Ответы [ 2 ]

2 голосов
/ 21 ноября 2011

Правильный ответ: ни один из них не является оптимальной архитектурой, но второй из них является лучшим вариантом.

Вы не должны никогда выставлять что-либо глобально. Объекты должны иметь только ссылки на объекты, которым они даны ссылки на http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons. Но если вы собираетесь это сделать, вам следует ограничить количество объектов, выполняющих конечный прогон вокруг их опубликованные API.

Могу ли я предложить вам сделать что-то еще? Современные фреймворки, такие как RobotLegs, обрабатывают это, предоставляя ссылку на один IEventDispatcher, который служит каналом связи или шиной событий. Одна очень хорошая концепция RobotLegs - это концепция Mediator, компонента, который просто слушает шину событий и передает изменения в компонент View, а также слушает компонент View и генерирует события, которые будут опубликованы на шине. .

Я упомянул Robotlegs, потому что во Flash он работает так же хорошо, как и во Flex. Вы также можете «свернуть свои собственные», прослушивая на сцене объекты, которые нужно добавить, а затем создавая контроллеры для них или вводя им данные (аналогично этому http://www.developria.com/2010/04/combining-the-timeline-with-oo.html). Однако Robotlegs относительно зрел к этому моменту и они разработали изломы, о которых вы, вероятно, еще не думали. Вы можете получить их на http://www.robotlegs.org.

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

1 голос
/ 21 ноября 2011

Ответ: это зависит. :)

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

Но обработка событий - довольно медленный механизм, и могут быть некоторые случаи, когда вы хотите, чтобы класс менеджера распространял уведомления в императивном стиле. Один (довольно грубый) пример: если у вас в игре много врагов, вам нужно обновить Event.ENTER_FRAME - добавление слушателя onEnterFrame для каждого отдельного объекта значительно замедлит ваше приложение по сравнению с вызовом update() метод для каждого экземпляра противника из класса EnemyManager. (Конечно, вы можете поймать ENTER_FRAME на каждом DisplayObject - как я уже сказал, это грубый пример, но он иллюстрирует мою точку зрения.)

...