![]() |
|
||||||||||
|
|||||
|
Регистрация: Jul 2009
Сообщений: 77
|
Вопрос по организации проекта, неверняка я изобретаю велосипед, поэтому просьба наставить на путь истенный.
Суть идеи: Проект состоит из двух основных типов объектов - "менеджеры" и "холдеры", помимо основного класса, конечно есть и другие, но это не принципиально. Менеджеры реагируют на события, обрабатывают их и сообщают об изменении своего состояния, сами ничего не отображают. Холдеры решений не принимают - это только контейнеры отбражаемых объектов, ловят сообщения менеджеров об изменениях и отбражают то, что им положено в данном состоянии. Напрямую объекты неимеют никаких связей, только менеджеры имеют публичные свойства, чтобы можно было определить их состояние в данный момент. Ни один холдер не имеет связи с другим холдером - табу. Никто не может сказать менеджеру изменить состояние, только он сам на основе приходящих эвентов. Как это работает: Когда что-то происходит в менеджере или холдере он шлёт соотв. эвент, основной класс его ловит и рассылает его всем менеджерам и холдерам. Заинтересованные объекты его обрабатывают и шлют свои эвенты, и так далее, Т.е. по сути работа программы это только обмен событиями через объект основного класса. Т.о. большинство основных элементов даже не подозревают о существовании других объектов - им приходит эвент, а кто его послал и из-за чего их не касается. Пример: ScreenManager - отвечает за состояния отображения всех объектов. ButtonManager - состояния всех кнопок. MenuHolder - отображаемых объект, в нём находится кнопка фулскрин. Пользователь кликает кнопку фулскрин в MenuHolder, кнопка шлёт эвент "кнопка фулскрин кликнута", сообщение ловит объект основного класса и рассылает его всем менеджерам и холдерам. Заинтересован только ScreenManager, остальные не реагируют. ScreenManager в ответ на это событие переводит плеер в полноэкранный режим и шлёт событие "ScreenManager изменил состояние на фулскрин" Его ловил основной объект, рассылает его всем менеджерам и холдерам. Но в нём заинтересован только ButtonManager, он решает кнопка фулскрин переходит в нажатое состояние и шлёт эвент "кнопка фулскрин нажатое состояние". Основной класс опять рассылает его всем. При этом ButtonManager понятия не имеет есть ли вообще кнопки фулскрин и сколько их и где они. Но этот эвент доходит до MenuHolder и он циклом по массиву кнопок сообщает всем им, что кнопка фулскрин нажата, ведь даже MenuHolder не знает какие именно кнопки он содержит. Кнопка фулскрин ловит это событие и нажимается! |
|
|||||
|
Регистрация: Nov 2010
Сообщений: 497
|
А в чем вопрос? Да, есть очень похожее решение. Называется message bus. Отличается от вашего только тем, как именно отправляет начальное сообщение компонент. В классическом варианте компонент имеет ссылку на шину (bus) и прямо в нее отправляет сообщение (а не отправляет событие наверх). Это обычно проще (не нужно поддержку EventDispatcher реализовывать).
Для клиентских приложений (flash, desktop application) тоже может быть применимо. А вот в вашем примере я бы не ButtonManager к шине прикручивал, а сами кнопки. Т.е. ButtonManager так же отправляет событие "fullscreenButtonPressed" и уже сама кнопка получает и обрабатывает событие. При чем там menu holder? Наверное, концептуально правильнее было бы даже так: Кнопка "фуллскрин" отправляет событие "request fullscreen". Screen manager получает и обрабатывает событие, отправляет новое - "set fullscreen mode". Его получает кнопка fullscreen (среди других обработчиков) и меняет свое состояние. Или менять взаимодействие между button manager и кнопками напрямую (хранить в button manager нужные ссылки). |
|
|||||
|
Регистрация: Jul 2009
Сообщений: 77
|
Спасибо за наводку, поищу информацию о message bus, для этого я и писал.
А на счёт вашего комментария, где "концептуально правильнее так", не согласен. Весь смысл в том что каждый принимает решения на своём уровне и не касается чужих дел. ScreenManager - управляет экраном, кнопки его не интересуют, Кнопка не может принимать решение нажаться ей или нет, ей думать неположено, она не знает о экранных режимах, она не знает зачем она нужна, у неё есть только имя. ButtonManager может её нажать или вообще отключить, и не конкретную кнопку, а кнопку с определёнными параметрами, потому что он не знает какие кнопки есть. MenuHolder нужен чтобы принимать сообщения от главного объекта, и спускать ниже - гланый объект не знает, что есть какие-то кнопки, они зарегистрированы в холдерах. Смысл такого построения, насколько это возможно, изолировать объекты друг от друга. Тогда программа будет как мозаика, можно дабавить или убавить объекты, другие этого не заметят. Напимер, добавление новой кнопки в MenuHolder сведётся лишь к её добавлению в массив кнопок. Последний раз редактировалось filepark; 29.03.2013 в 12:08. |
|
|||||
|
Регистрация: Nov 2010
Сообщений: 497
|
Цитата:
Или можно оставить и как у вас - "локальную" шину для меню, при этом транслировать сообщения из "глобальной" шины в "локальную". Подход удобен для объектов с различным временем жизни. Например, для какого-то диалога временно подписать его на шину, а потом отписать. Мои замечания касаются даже не столько идеологии (там все нормально), а технической реализации. Чтобы не писать отдельно "диспетчеризацию" для MenuHolder, подобную же диспетчеризацию - для диалогов и т.п. А чтобы можно было взять "message bus" и "message bus translator", например, и использовать везде их. В общем, на это все нужно в коде смотреть. |
![]() |
![]() |
Часовой пояс GMT +4, время: 19:35. |
|
|
« Предыдущая тема | Следующая тема » |
|
|