Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 23.12.2012, 13:06
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 1  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
По умолчанию Модель, события изменения

У меня вопрос по архитектуре модели и принципу поимки факта изменения данных внутри её.

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

Очевидно, модель должна слушать этот объект на событие изменения, который тот должен будет послать ей. А после этого, уже послать своё событие об изменений состояния.
Итого, если мы меняем в модели данный на уровень глубже, то-есть например: model.auto.bmw = 0;
То произойдет диспетчеризация сразу 2 событий, сначала объект auto уведомит модель об изменений свойства bmw, а затем уже модель пошлет событие изменения состояния.

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

Старый 23.12.2012, 13:55
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 2  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Да, есть. Не рассматривать модель как свалку хэшей, "базу данных". Приличная Модель не должна давать доступ к своим деткам направо и налево. Все контроллеры должны придерживаться регламента и менять что-то только через специальные методы, предоставляемые моделью, в идеале еще и ограниченные индивидуальными для каждого контроллера интерфейсами.
__________________
Reality.getBounds(this);

Старый 23.12.2012, 15:08
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 3  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Очевидно, модель должна слушать этот объект на событие изменения, который тот должен будет послать ей. А после этого, уже послать своё событие об изменений состояния.
Итого, если мы меняем в модели данный на уровень глубже, то-есть например: model.auto.bmw = 0;
Не, лучше чтобы модель никого не слушала.
Т.е. если есть ребёнок - он сам диспетчит изменения
И кому надо - подписывается на ребёнка

Максимум - события всплывают до главной модели и кому надо подписываются на неё, ловя события детей.
Максимум2 - модель ловит события от детей и просто диспетчит переиначенные свои, но ничего не правит в других частях.

А если надо что-то делать при изменении детей с остальными данными - лучше сбоку контроллер навернуть (в модель не лазить!), и лучше чтобы тот кто меняет - сам вызывал метод контроллера меняющий другие части, или вызывал комманду. Просто так проще за всем уследить.

Бывает, конечно, что тому, кто меняет лучше не знать, например, о панельке со списком текущих событий в игре (ну в социалках бывает на экране вывешивают список ["созрел фрукт, надо собрать", "здание поломалось надо починить", ...]). Тогда создается контроллер, который слушает модель и правит список этот по необходимости (саму модель слушает, всплывающие изменения детей слушает).

Но в основном - события изменения частей модели и самой модели - это для обновления вида (согласовывать обновление вида через модель в разы проще чем вызывать непойми какие методы непонятно в когда появляющихся и исчезающих вьюшек), а не для того, чтобы изменить другие части и что-то пересчитать - иначе с зацикливанием событий не разгребёшь.

Цитата:
Меня это немного смущает, а что если иерархия вложенности будет ещё больше? Может быть есть другой способ, узнать в модели произошло чтение или запись в дочерних объектах?
Можно вручную после изменения ребёнка вызвать метод модели, например dispatchItemChange(item:Item), во всех местах.
Не самый плохой способ, даёт больше контроля над диспетчингом, может даже общие объемы кода будут меньше.
Недостаток понятен - нужно больше внимания, чтобы не забыть вызвать везде этот метод.
Но с другой стороны меньше гемороя с поиском багов в "автоматически" работающем диспетчинге, когда что-то обновляется в неподходящий момент, или того хуже - зацикливается.
На практике получается, что половина событий идет автоматом - половина вызвается вручную.


Последний раз редактировалось expl; 23.12.2012 в 15:23.
Старый 23.12.2012, 17:44
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 4  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
Где в users будет какой нибудь класс менеджер для работы со списком.
Ага. UsersModel называется.
Исторически сложилось два основных подхода к роли Модели. Один из них — Модель как свалка для хранения всего и вся, а логика приложения пораспихана по ТТУК (Толстые Тупые Уродливые Контроллеры). Это, по всей видимости, то что Вы имеете сейчас. Контроллер как бы логический класс, хранящий свой массив данных не под собственным матрасом, а в банке у Модели.
Второй подход (классический MVC) — Модель является не базой данных, а моделью состояния приложения, и содержит в себе всю логику работы с данными. В этом варианте нет места модели как сторожу свалки со свистком. Это то, к чему Вы подсознательно стремитесь. Но это не значит, что Тупой Толстой Уродливой должна быть Модель. Модель может быть композитной. Модели-дети должны быть четко известны главной фасадной модели. Им необязательно пуляться событиями в свою маму, если мама исполняет роль фасада. То есть дети могут получать свои детские сообщения от своих детских контроллеров и либо диспатчить события изменения своим детским вьюхам (по сути просто несколько параллельных MVC), либо вызывать диспатч из модели-фасада (больше порядка / меньше хаоса). Просто не рассматривайте Модель как один единственный класс. Это может быть целый самостоятельный паттерн, одним классом представленный только для слушателей. Просто.. если контроллер ДУМАЕТ, что ему делать с новыми данными, каким моделям-детям их раздавать и т.п., он становится Толстым и Уродливым, ему надо знать слишком много о Модели и о значении этих данных. Контроллер должен не более чем передать по назначению важные действия юзера во вьюхе. Если эти действия интересуют только какой-то один логический блок модели, то лучше именно эту под-модель и передать данному контроллеру для общения сразу при инициализации. Здесь весь смысл в том чтобы сместить логику из контроллеров в модельки — потому что моделям проще обмениваться расчетными данными между собой в своем семейном болоте, чем контроллерам, которые де-юре ничего друг о друге не знают и поэтому сколько-нибудь приличную логику обеспечить не могут (Тупые).
__________________
Reality.getBounds(this);

Старый 23.12.2012, 17:51
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 5  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Просто.. если контроллер ДУМАЕТ, что ему делать с новыми данными, каким моделям-детям их раздавать и т.п., он становится Толстым и Уродливым, ему надо знать слишком много о Модели и о значении этих данных.
Контроллер - это то что меняет данные, определение вроде такое, да?
Как в социалках:
изменение данных и способ изменения зависит от того, что за окно открыто, что сервер прислал, какое сегодня число и какой режим редактирования на карте. Т.е пихать это в модель нет смысла.
Половина логики - это даже не объекты-контроллеры, которые что-то делают, а просто асинхронные классы-комманды, которые что-то отрправляют на сервер и меняют данные.

Есть ещё контроллеры, которые работают во времени и зависят только от состояния данных - т.е. обеспечивают рост растений, появление прибыли и т.д. Их впринципе можно загнать в модель, но они и отдельно нормально живут.

Я бы не заявлял что в модель надо пихать логику. Ситуативно всё.

Старый 23.12.2012, 17:57
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 6  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
Спорить про MVC - бессмысленно)

Добавлено через 56 секунд
У каждого он свой, я даже больше скажу, у меня даже для разных проектов он разный. Да и в одном проекте может быть несколько разных mvc.
__________________
Отряд Котовскага

Старый 23.12.2012, 20:56
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 7  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
В таком случае смысл вопроса от меня ускользает — делайте как советовал in4core, пусть контроллер, "меняющий данные", сам и извещает об этом вьюху. Если модель — пассивная БД, то смущаться уже нечего. Можно отложить и все остальное, что Вы читали о классическом MVC.
__________________
Reality.getBounds(this);

Старый 23.12.2012, 21:48
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 8  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
делайте как советовал in4core, пусть контроллер, "меняющий данные", сам и извещает об этом вьюху
Это драматически увеличивает объемы условной логики в контроллере, если вьюх больше одной или время её существования на экране непостоянно. Но есть ситуации, в которых так и надо делать.
Цитата:
Если модель — пассивная БД
Один из вариантов реализации MVC, не самый плохой.
Цитата:
Можно отложить и все остальное, что Вы читали о классическом MVC.
Где эти скрижали с этим MVC?

А вопрос, насколько я понял (хоть и написал выше стену текста) был в том, что человеку не хотелось писать кучу кода, который только редиспетчит события от детей,
тут вызов в ручную - как-бы вариант,
реализация универсального баблинга в моделях - тоже вариант, но требующий аккуратности и понимания чего делаешь (это просто делается только при наследовании моделек от Sprite, или композицией с Sprite, чтобы лишние поля от Sprite не мешались, а если самому делать - придётся подключать мозг)
Вот вроде и всё.

Старый 23.12.2012, 21:49
dimarik вне форума Посмотреть профиль Отправить личное сообщение для dimarik Найти все сообщения от dimarik
  № 9  
Ответить с цитированием
dimarik
.
 
Аватар для dimarik

модератор форума
Регистрация: Sep 2003
Адрес: Москва
Сообщений: 4,630
Записей в блоге: 20
Цитата:
Можно вручную после изменения ребёнка вызвать метод модели, например dispatchItemChange(item:Item), во всех местах.
Коммит изменений переносится на представление. Не нужно дергать dispatchItemChange (классический notifyObservers). Представления на Event.RENDER изменяются в соответствии с текущими изменившимися свойствами модели. Профит.
__________________
Воспитан в TimeZero. Работаю в Mail.ru.

Старый 23.12.2012, 21:59
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 10  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Коммит изменений переносится на представление. Не нужно дергать dispatchItemChange (классический notifyObservers). Представления на Event.RENDER изменяются в соответствии с текущими изменившимися свойствами модели. Профит.
Отложенная валидация?
Ресурсы, оно, конечно экономит.
Но в модели реализуется не проще, чем редиспетчинг.
Плюс в обработчике onRender во вьюхе будет куча if (model.fieldChanged) {...}.
Хотя, когда порядок изменений вьюхе известен - их проще держать под контролем - надо взять на вооружение.
Но автора, по-моему именно проброска изменений с детей в старшие модели напрягала.

Стоп!
Код в модели
Код AS3:
public function set money(value:int) {
    _money = value;
    moneyChanged = true;
}
public var moneyChanged:Boolean = false;
Код во вьюхе
Код AS3:
public function onRender(event:Event):void {
    if (_model.moneyChanged) {
        _moneyTF.text = _model.money + "$";
       _model.moneyChanged = false;// А другие модели как будут изменения слушать?
    }
}
Как это делается то, где флаги изменений сбрасываются?
Просто в ENTER_FRAME всё подрят сбрасывается? Потому что он должен сработать после RENDER?


Последний раз редактировалось expl; 23.12.2012 в 22:16.
Создать новую тему Ответ Часовой пояс GMT +4, время: 00:26.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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