Страница 2 из 3
Re: Архитектура приложения
Добавлено: 27 мар 2014, 14:30
Agiliter
alexandr_ratush писал(а):Пример из контролера:
Код: Выделить всё
var _agentVK:AgentVK = new AgentVK(_model.socialData);
Благодарен за совет и разъяснение
В первоначальном варианте выдало ошибку, но было легко поправлено)
Код: Выделить всё
var _data:Object = _model.getSocialData(); agentVK = new AgentVK(_data);
Re: Архитектура приложения
Добавлено: 27 мар 2014, 16:15
Agiliter
Мда. Слона-то и не заметил
А как View "узнает" об изменении в модели? Если реализовывать паттерн Наблюдатель, то получается, что Модель - это издатель, а Представление - подписчик, я так понимаю. Если я верно мыслю, то в модели нужно создать массив, в который нужно занести всех возможных подписчиков, ну как минимум одно Представление. Потом в модели прописать метод, который бы вызывал у всех подписчиков метод апдейта. Но этот view будет же не тем же самым объектом, с которым будет работать контроллер. Или же в таком случае нужно в контроллере передавать view в модель? Вопрос оповещения об изменении модели очень интересен и важен для меня.
Re: Архитектура приложения
Добавлено: 27 мар 2014, 17:10
alexandr_ratush
В событийной модели флеш уже реализован паттерн Наблюдатель.
Или же в таком случае нужно в контроллере передавать view в модель?
Ни в коем случае. Вид должен обрабатывать данные модели и отображать их как ему угодно.
К примеру в модели есть данные для графиков. И у Виде вы можете отобразить их с помощью линий, столбиков, секторами кругов или как вам угодно. Это и есть свобода.
Принцип примерно такой:
1. После изменений данных в модели, отправляем событие в поток
, для этого модель должна наследовать EventDispatcher.
2. У Виде мы подписываемся на модель
Код: Выделить всё
_model.addEventListener(SET_SOCIAL_DATA, setSocialHandler);
и обрабатываем их.
Re: Архитектура приложения
Добавлено: 27 мар 2014, 17:49
Agiliter
alexandr_ratush писал(а): У Виде мы подписываемся на модель
Код: Выделить всё
_model.addEventListener(SET_SOCIAL_DATA, setSocialHandler);
Вот опять) Получается, что в Вид передается модель? Как можно в Виде к _model адлистенер присобачить, если Модель и Вид общаются только через контроллер?
В Main:
Код: Выделить всё
var view:View = new View(); var model:Model = new Model(data); var controller:Controller = new Controller(view, model); controller.init(); addChild(view);
А затем
Код: Выделить всё
public function Controller(view:View, model:Model) { _model = model; _view = view; } public function init():void { _model.init(); _view.init(); clientServer = new MyClientServer(); var data:Object = _model.getSocialData(); agentVK = new AgentVK(data); }
Не нужно ли тогда var view:View = new View(model)?
Re: Архитектура приложения
Добавлено: 27 мар 2014, 18:28
Agiliter
Или же после изменений данных в Модели, отправляем событие в поток, а на Модель подписываемся в Контроллере, который вызывает метод апдейта Вида
Re: Архитектура приложения
Добавлено: 27 мар 2014, 21:15
alexandr_ratush
Получается, что в Вид передается модель? Как можно в Виде к _model адлистенер присобачить, если Модель и Вид общаются только через контроллер?
Есть понятие активная и пассивная модель
Википедия
Я в своих проектах использую активную модель.
Вот собственно код создания триады MVC
Main:
Код: Выделить всё
package { import controllers.Controller; import flash.display.Sprite; import flash.events.Event; import models.Model; import views.View; /** * ... * @author ratush */ public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); var _model:Model; var _view:View = new View(); var _controller:Controller = new Controller(_model, _view); _controller.init(); addChild(_view); } } }
Controller:
Код: Выделить всё
package controllers { import models.Model; import views.View; /** * ... * @author ratush */ public class Controller { private var _model:Model; private var _view:View; public function Controller(model:Model, view:View) { _model = model; _view = view; } public function init():void { _model = Model.init(); _view.init(_model); } } }
Model:
Код: Выделить всё
package models { import flash.events.EventDispatcher; /** * ... * @author ratush */ public class Model extends EventDispatcher { //SINGLETON vars private static var instance:Model; private static var allowInstance:Boolean; public function Model() { if (allowInstance == false) { throw new Error("Error: use Model.init()"); } } /** * Singleton function * @return */ public static function init():Model { if(instance == null) { allowInstance = true; instance = new Model(); allowInstance = false; } else{ trace("Singleton instance already exists."); } return instance; } } }
View:
Код: Выделить всё
package views { import flash.display.Sprite; import models.Model; /** * ... * @author ratush */ public class View extends Sprite { private var _model:Model; public function View() { } public function init(model:Model):void { _model = model; } } }
Re: Архитектура приложения
Добавлено: 28 мар 2014, 12:02
Agiliter
Большое спасибо
Хочу уточнить еще один момент. Реакцию на действия пользователя реализуем в Контроллере? Например, кнопки рисуются в Виде. А при нажатии что происходит? Нажатие кнопки, созданной в Виде должен обрабатывать Контроллер? Как?
А если такая реализация? Общая схема
Код: Выделить всё
var _model:Model = new Model();var _controller:Controller = new Controller(_model);var _view:View = new View(_model, _controller);
Тогда пользователь приложения взаимодействует с элементом интерфейса пользователя (например, нажимает на кнопку в Виде).
Вид посылает соответствующее событие Контроллеру, чтобы он решил, как его нужно обработать. Что-то вроде
Код: Выделить всё
btn.addEventListener(MouseEvent.CLICK, _controller.func);
Контроллер производит изменения в Модели на основе своего решения о том, как следует обработать это событие.
Модель информирует Вид об изменении своего состояния.
Вид считывает информацию о новом состоянии и обновляет себя.
Код: Выделить всё
_model.addEventListener(SET_SOCIAL_DATA, update);
Или тут есть какой-то косяк, который моему неоптыному взгляду незаметен?
Re: Архитектура приложения
Добавлено: 29 мар 2014, 17:45
Alazaur
Хочу уточнить еще один момент. Реакцию на действия пользователя реализуем в Контроллере? Например, кнопки рисуются в Виде. А при нажатии что происходит? Нажатие кнопки, созданной в Виде должен обрабатывать Контроллер? Как?
Agiliter, вьюшка диспатчит событие, контоллер его ловит и дергает модель. Основная суть здесь в том, чтобы сделать модель и вью обособленными. Выражение контроллер меняет модель несовсем верно. контроллер ничего не меняет в модели. Модель предоставляет ему некоторый ограниченный интерфейс открытых методов, после вызова которых она решит, что делать, как-то реагировать или нет.
Re: Архитектура приложения
Добавлено: 31 мар 2014, 14:36
Agiliter
ок. Общий принцип понял. Сделал простенькую тест программу на основе MVC. При нажатии кнопки View
Код: Выделить всё
btn.addEventListener(MouseEvent.CLICK, buttonClick);
диспатчит событие
Код: Выделить всё
dispatchEvent(new Event(EventTypes.SET_HP));
Контроллер его ловит
Код: Выделить всё
_view.addEventListener(EventTypes.SET_HP, setHP);
и вызывает метод Модели
Этот метод диспатчит событие
Код: Выделить всё
dispatchEvent(new Event(EventTypes.SET_HP));
которое ловит вьюшка
Код: Выделить всё
_model.addEventListener(EventTypes.SET_HP, viewHP);
Круг замкнулся
Делал на трейсах, и всё хорошо отработало. Но проблема в том, что кнопку пришлось делать прямо во View. Я до этого создавал класс MyWindow, который отвечает за создание полноценных окошек с кнопками. И поэтому хотел его и использовать для создания окошек во View?
private var myWindow:MyWindow;
myWindow.mainWindow();
Однако, в таком случае, когда нажатие на кнопку обрабатывается не прямиком во View (а в классе MyWindow, где и создается), я не знаю как диспатчить событие, чтобы контроллер его поймал. Если кнопка создается и описывается её реакцию во вьюшке, то без проблем, а если уже в классе MyWindow, то получается, что в контроллере нужна ссылка на MyWindow и независимость Вида и Контроллера теряется
Re: Архитектура приложения
Добавлено: 31 мар 2014, 15:33
alexandr_ratush
Как известно объекты из списка отображения имеют свойство оповещать что у них наступило событие (фазы захвата и всплытия).
Вы же можете в контролере подписать объект класса
MyWindow на событие:
Код: Выделить всё
_view.myWindow.addEventListener(EventTypes.SET_HP, setHP);
И когда будет нажата кнопка, об этом узнает myWindow, _view и контролер.
а если уже в классе MyWindow, то получается, что в контроллере нужна ссылка на MyWindow и независимость Вида и Контроллера теряется
Подкину еще вам дровишек в огонь.
Посмотрите в сторону патерна
Медиатор. Может он вам поможет.