Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Статьи (http://www.flasher.ru/forum/forumdisplay.php?f=101)
-   -   Хорошее MVC (http://www.flasher.ru/forum/showthread.php?t=138349)

etc 01.03.2011 19:34

Psycho Tiger, спорно ровно до того момента, когда мы поменяем вьювер. И тогда контроллер, который гонял квадратики, с шариками уже не управится.

cr0w312, никак, ей это не нужно. Узнает вьювер всей трассы, сообщит контроллеру. Контроллер уже дальше решит, сломать машинку или нет (оперируя только моделью машины, а не её вьювером!). Либо другой вариант — контроллер перед изменением координат сначала узнает, можно ли в них попасть. А вот у кого он это узнает, от модели или от вьювера — зависит от конкретного проекта.

cr0w312 01.03.2011 19:40

Цитата:

Сообщение от etc (Сообщение 977328)
cr0w312, никак, ей это не нужно. Узнает вьювер всей трассы, сообщит контроллеру. Контроллер уже дальше решит, сломать машинку или нет (оперируя только моделью машины, а не её вьювером!). Либо другой вариант — контроллер перед изменением координат сначала узнает, можно ли в них попасть. А вот у кого он это узнает, от модели или от вьювера — зависит от конкретного проекта.

Браво. Вопрос исчерпан, спасибо(отзывы к твоим постам почему-то не добавляются:( )!

Psycho Tiger 01.03.2011 20:21

Цитата:

Psycho Tiger, спорно ровно до того момента, когда мы поменяем вьювер. И тогда контроллер, который гонял квадратики, с шариками уже не управится.
Ну, ага. А в случае если они должны отскочить при пересечении то придётся ещё менять и контроллер: физика столкновений квадрата не такая, как у круга. Обобщая чуть дальше можно придти к выходу, что в "более общем" подходе в контроллер нужно ещё передавать и характер столкновения и вообще много чего, вроде состояния объектов после столкновения.
Спорно сколько информации должен сообщить вью контроллере при столкновении.

terbooter 02.03.2011 00:55

Цитата:

Сообщение от etc (Сообщение 977328)
Либо другой вариант — контроллер перед изменением координат сначала узнает, можно ли в них попасть. А вот у кого он это узнает, от модели или от вьювера — зависит от конкретного проекта.

По Таймеру или enterFrame-у ?

Psycho Tiger 02.03.2011 01:04

@terbooter: это где ты такой пост увидел? =)

@etc, в цитате terbooter`а: Вот это уже как я обычно делаю.

cr0w312 02.03.2011 02:29

Цитата:

Сообщение от Psycho Tiger (Сообщение 977420)
@terbooter: это где ты такой пост увидел? =)

@etc, в цитате terbooter`а: Вот это уже как я обычно делаю.

оффтоп: это пост первую строчку которого ты процитировал 3 поста назад. А на форуме есть тег сполера?

etc 02.03.2011 11:17

Цитата:

Сообщение от terbooter (Сообщение 977418)
По Таймеру или enterFrame-у ?

По событию от вью «Я хочу туда!». А туда нельзя, например.

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

Сообщение от Psycho Tiger (Сообщение 977349)
Ну, ага. А в случае если они должны отскочить при пересечении то придётся ещё менять и контроллер: физика столкновений квадрата не такая, как у круга. Обобщая чуть дальше можно придти к выходу, что в "более общем" подходе в контроллер нужно ещё передавать и характер столкновения и вообще много чего, вроде состояния объектов после столкновения.
Спорно сколько информации должен сообщить вью контроллере при столкновении.

Пусть отскакивают, контроллеру на это наплевать. Ему нужно знать, кто с кем столкнулся и какие последствия. Непосредственно физики в нём нет.
Въехав, например, на машине в столб, твоей страховой совершенно пофиг, под каким углом и сколько раз тебя крутило вокруг оси, ей интересен лишь ущерб.

cr0w312 02.03.2011 12:36

Цитата:

Сообщение от etc (Сообщение 977478)
Пусть отскакивают, контроллеру на это наплевать. Ему нужно знать, кто с кем столкнулся и какие последствия. Непосредственно физики в нём нет.
Въехав, например, на машине в столб, твоей страховой совершенно пофиг, под каким углом и сколько раз тебя крутило вокруг оси, ей интересен лишь ущерб.

трассаView.as
Код AS3:

 
      var объектыДляОбсчетаСтолкновений:Array = new Array();
      объектыДляОбсчетаСтолкновений.push(мувикСтена);
      объектыДляОбсчетаСтолкновений.push(мувикСтолб);
 
        мувикАвто.addEventListener(Event.CHANGE_POSITION, проверкаКоллизийHandler);
 
        private function проверкаКоллизий(e:Event):void
          {
                for(var i:int=0;объектыДляОбсчетаСтолкновений.length;i++)
                  {
                      if(e.currentTarget.hitTestObject(объектыДляОбсчетаСтолкновений[i])
                          {
                              super.dispatchEvent(new Event(Event.МАШИНКА_ВЛУПИЛАСЬ));
                          }
                  }
            }

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

Psycho Tiger 02.03.2011 13:46

Цитата:

Пусть отскакивают, контроллеру на это наплевать. Ему нужно знать, кто с кем столкнулся и какие последствия. Непосредственно физики в нём нет.
Въехав, например, на машине в столб, твоей страховой совершенно пофиг, под каким углом и сколько раз тебя крутило вокруг оси, ей интересен лишь ущерб.
Физики нет в контроллере? Тогда вью говорит контроллеру какие последствия и вью, без раздумий, меняет модель на основании того, что подсказала вьюха?

etc 02.03.2011 16:26

Psycho Tiger, это зависит от того, какие именно данные находятся в модели. Если это бильярд, например, то значения x, y, скорости и прочие параметры не нужны в модели. В модели только номер шара и в лунке он или нет. Вью получает коллекцию шаров и гоняет её по экрану, с собственными координатами. При попадании в лунку, шлёт событие. Далее контроллер решает, что забита 8-ка, то значит начисляем столько-то. Физики в контроллере нет, он рулит только по правилам игры.
Безусловно, смотря что понимать под контроллером. Гоняющий шары вью — это в некотором понимании контроллер физики + вью. В моём личном понимании контроллер занимается бизнес-логикой.

Psycho Tiger 02.03.2011 20:54

Хм, забавно. Я всегда представлял себе модель как "полное состояние игры", по которому можно восстановить процесс игры полностью. То есть, имея на руках модель и сериализатор этой модели можно сохранить её куда нибудь (например, в SharedObject), а потом загрузить, получив ту же самую ситуацию. То есть угол поворота шарика для бильярда — речь о том угле, который крутит шар в оси, который, по сути, меняет только положение циферки-номера шара на шаре — вот он не попадает в модель, потому что неважный. А координаты, соответственно, попадают.
Вообще именно ты мне рассказал об MVC и образовал в моей голове костяк информации об этой теме, а сейчас рушишь мои пирамиды знаний )
Как на самом деле?

etc 02.03.2011 22:23

И координаты не попадают :)
В модели хранится ровно та информация, которая действительно необходима всему приложению.

Psycho Tiger 02.03.2011 22:31

В бильярде я вижу такую модель игры:
GameModel
- Players:Player (Array)
- Balls:Ball (Array)
- turnId:int (индекс в массиве players)
- misc (ерунда, вроде рейтинговый матч или нет/and so on)

Соответственно Ball имеет x,y,scored,num.
Почему x,y не нужны всему приложению? Они нужны вьюхе. Кроме того, получив состояние игры с сервера нужно как-то расположить шары на поле. Приказывать вьюхе прямо? Последнее время мне совсем не нравится это дело. Приказы контроллер-вью я передаю через модель.

etc 02.03.2011 22:50

x, y больше никому, кроме вью и не нужен, соответственно нет смысла хранить это и на сервере, он все равно не справится с контролем каждого клиента.

Psycho Tiger 02.03.2011 23:34

Ну так, примерно понятно. То есть можно трактовать это так: "в модели хранится то, что гипотетически может быть послано на сервер". В двойных кавычках, конечно.

Цитата:

он все равно не справится с контролем каждого клиента.
Объясни про вот это пожалуйста.

Котяра 03.03.2011 01:30

По мне, тут нет однозначного правила.
В ммо - всегда хранятся координаты персонажей, например.
В бильярде - Xто Знает. Как решено проверять логику, если не надо проверять на физику ударов от читеров, то координаты и не нужны.. Хотя для реконнектов всё равно пригодились бы..

cr0w312 03.03.2011 06:17

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

Добавлено через 2 часа 6 минут
А. Модель хранит в себе то, что необходимо в конкретной ситуации(имеется ввиду не в определенный момент времени, а реализация проекта)? Контроллер принимает решения типа "Нада памыть пасуду" и т.п. а вьюшка уже идет и моет посуду, идет она по своей воле ее не толкает контролер, а модель просто знает чем сейчас занята вьюшка, и если пользователь пхнет мышой во вьюшку, мол хватит, вьюшка сама по себе не перестанет мыть посуду(ну чисто визуально), она посылает контроллеру вопрос - мол хватит?, контроллер оценит степень чистоты посуды и вынесет решение - модель, мыть посуду еще 10 секунд. Вьюшка слушает изменения модели и через 10 сек заканчивает. Ну вот, снова получилось "на пальцах" и никакой конкретики.

etc 03.03.2011 17:14

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

Котяра, а что реконнект, клиент может и не закрывать сессию, отвалился-подключился, сервер состояние и так помнит.

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

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

Dukobpa3 03.03.2011 18:50

Могу пример привести из моего любимого Toribash.

Физика там вся в клиенте, во вьюхе.
На сервак отправляются просто команды следующего хода - согнуть коленку, выпрямить локоть.
Сервак пересылает клиенту номер рас команды от клиента номер два, а клиенту номер два команды от клиента номер рас.

Потом оба клиента получив оба пакета команд у себя это отрисовывают, независимо от сервера (модели).

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

etc 03.03.2011 20:31

Dukobpa3, ну да, примерно так. Только физику надо округлять, чтобы точно было одинаково.

Dukobpa3 03.03.2011 23:39

Вложений: 2
Немного не флешовый вопрос.
Рисую архитектуру сервера на питоне. Прошу поглядеть и поправить.
Заранее спасибо.
Вложение 26134

И второй вариант:
Вложение 26133

Я слегка запутался))

terbooter 04.03.2011 09:50

Про бильярд.
Вьюха которая гоняет шары, это уже полноценный модуль, который я бы тоже строил по архитектуре МВЦ.
То есть есть большое МВЦ - это весь проект клиента. Там команды выполняют бизнес-логику своего уровня (счет, победа, новая игра). И вот одна из вьюх большого МВЦ тоже устроена по схеме МВЦ - это маленькая МВЦ. Там есть своя модель, которая хранит координаты шариков, и свои команды, которые по enter frame гоняют шарики.
Если мы захотим сделать минимэп бильярдного поля - нет проблем, делаем в Большом МВЦ команду, которая будет спрашивать убольшой вьюхи координаты всех шаров. А большая вьюха хранит эти координаты в маленькой модели.

Dukobpa3 04.03.2011 09:54

terbooter, ну вообще тут страниц пять обсуждения мусолили то что каждый элемент триады может в свою очередь быть триадой :)

terbooter 04.03.2011 09:54

Мне очень нравится сравнение конструирования ПО со строительством. (Шаблоны проектирования вначале появились именно в архитектуре зданий=))
Так вот если мы строим город, то применяем некоторый шаблон. У нас есть спальные районы, бизнес-районы, парки отдыха. Если увеличить масштаб, то можно увидеть повторение этого же шаблона - в каждом районе есть столовая, детсад и школа. Если еще увеличить, то в каждой квартире есть спальня, кухня, рабочий кабинет. Опять тот же шаблон.
Так почему в проекте один шаблон ДОЛЖЕН быть применет ТОЛЬКО ОДИН раз?

Добавлено через 4 минуты
Dukobpa3, не сомневаюсь. Я внимательно читаю эту тему, как и все остальные темы в которых я пишу.
Потому и еще раз напомнил, про вложенность. А то про это как то забывается у многих

cr0w312 04.03.2011 15:27

Вот меня сильно интересует вложенность
предположим
Код AS3:

/***********************************************
**    класс главной вьюшки                  **
***********************************************/

package
{
  public class View extends Sprite
  {
        private var _model:Model;
 
        public function View(model)
        {
            _model = model;
            this.addListener(MouseEvent.MOUSE_CLICK, onMouseClickAddNewMVC);
        }
 
        private function onMouseClickAddNewMVC(e:MouseEvent):void
        {
            var cController:CarController = new CarController(this);
        }
    }
}
/***********************************************
**              класс КарКонтроллер          **
***********************************************/

package
 {
 
  public Class CarController
    {
      private var _host:View;
 
      public funcrion CarController(parentView)
        {
          _host = parentView;
          var cModel:CarModel = new CarModel();
          var cView:CarView = new CarView(cModel);
          _host.addChild(cView);
        }
    }
 }

так верно или я путаю тёплое с мягким?

Psycho Tiger 04.03.2011 15:35

Dukobpa3, terbooter, фух, вы меня успокоили =) Да, у меня каждый элемент тоже триада. etc мне говорил про самую "большую" структуру приложения, а я больше углублялся именно в "мелкие". Теперь всё укладывается в моё понимание, всем спасибо.

Добавлено через 1 минуту
@cr0w312, да, правильно.
Но лично мне приятней чтобы контроллер создавал контроллер и никто больше.

gloomyBrain 04.03.2011 15:42

я бы так делал
Код AS3:

/***********************************************
**              класс КарКонтроллер          **
***********************************************/

package
{
 
  public Class CarController
    {
      private var _view:CarView;
      private var _model:CarModel;
 
      public funcrion CarController()
        {
          _model:CarModel = new CarModel();
          _cView:CarView = new CarView(cModel);
        }
 
      public function get view():CarView
      {
              return _cview;
      }
 
      public function get view():CarView
      {
              return _cview;
      }
 
        public function get model():CarModel
      {
              return _model;
      }
    }
 }

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

cr0w312 04.03.2011 15:45

Цитата:

Сообщение от Psycho Tiger (Сообщение 978027)
@cr0w312, да, правильно.
Но лично мне приятней чтобы контроллер создавал контроллер и никто больше.

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

Psycho Tiger 04.03.2011 15:55

Ага, примерно так.

Zebestov 26.03.2011 15:54

http://ru.wikipedia.org/wiki/Model-View-Controller
Конкретно раздел "Наиболее частые ошибки". Я уже писал здесь ранее, что склоняюсь к тонкой прокладке (Controller) между логикой (Model) и ее отображением (View).

fish_r 05.06.2011 01:11

Вот такой вопрос в разрезе MVC. Предположим использую я в программе какой-то внешний, по отношению к программе объект. Он также имеет структуру MVC. В моей программе он отображает содержимое, которое моя программа ему сообщила ранее и изменяет его, специф. образом, по сигналу моей программы. Так как же их завязывать? Какая часть этого, внешнего, объекта будет выражать его самого, что мне экземпляры контролов создавать что ли? Тогда не странно ли будет создавать контролл а добавлять на сцену переданную им ссылку, а общаться опять же через контролл? Что будет интерфейсом этого объекта? Ведь мы привыкли создавая объект, нами он написан или нет неважно, общаться с ним же, а не с его контролом. Не создается впечатления черезголовуштанынадевания?

etc 05.06.2011 23:14

Если это внешний объект, то у него должен быть интерфейс модуля и работать мы с ним должны как с view если он таковым является.

fish_r 06.06.2011 00:45

А как это "интерфейс модуля"?
Подумал, подумал... В этом случае "фасад" подходит, который является DisplayObjectContainer-ом. Приложение общается с ним думая, что он и есть объект, а он сообщает контролу всё необходимое, в тоже время использует преимущества InteractiveObject-а (подписка на события и пр.). То есть мы можем его и "пощупать" и сказать ему что нибудь, вместо того, чтобы "щупать" одного, а говорить другому.
Как такой вариант?

fish_r 09.06.2011 15:28

Ещё один момент есть... Сам с собой разговариваю ... :). Смущает то, что контролл зачастую просто транслирует данные через свои сеттеры в сеттеры модели получается дубляж переменных в обоих классах.
Насколько плохим тоном является размещение в сеттере контролла сеттера модели? Без промежуточных переменных, когда они никак не используются в контролле, конечно. То есть получается конструкция типа:

Код AS3:

 
public class Controll() extends EventDispatcher
{
...
 
    private var _model:Model = new Model();
 
    ...
    public function get param():Object { return _model.param; }
    public function set param(obj:Object):void
    {
          if  ( _model.param === obj ) return;
          _model.param = obj;
 
    }
...


Dukobpa3 09.06.2011 15:35

Эмммм... я хз конечно но в моем представлении контролу сеттеры вообще нафиг не надо, это жеж обсервер чистой воды.

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

(может это я разбаловался pureMVC и Robotlegs просто, но там есть система нотификейшенов, через которую контроллеры между собой общаются, потому там нет нужды главному контроллеру что-то дергать в дочернем, и главный контроллер просто шлет нотификейшен)

fish_r 09.06.2011 18:39

роботлегс не читал, а в pureMVC нотификешен - это объект-событие с именем и данными, так кажется?

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

а там в методе-слушателе сразу дергается сеттер модели? если конечно цель - только передать в модель новые данные.

Dukobpa3 09.06.2011 18:57

ну суть в том что нотификейшен имеет имя и данные и это впринципе всё что надо знать.

Это просто инструмент а как его использовать уже вопрос левый. Я зачастую шлю нотификейшены даже без данных, такое себе глобальное событие просто. А когда с данными то опять же два варианта, часто просто достаточно в контроллере разобрать эти данные и сделать выводы, а иногда и запушить эти данные в модель.

Но как я сказал выше - я стараюсь делать так чтоб контроллер напрямую вьюхой не рулил, поэтому практически каждый нотификейшн ведет к тому что контроллер что-то меняет в модели.

Но опять же по ситуации))) Панацеи нету :)

Добавлено через 6 минут
Тут еще стоит понимать что контролер получивший нотификацию может быть каким-то высокоуровневым контроллером на уровне всего приложения, а не рулящий каким-то маленьким модулем, тогда получив нотификацию он ничего никуда не записывает а просто посылает уже другую нотификацию, так сказать адресную.

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

fish_r 09.06.2011 21:15

Цитата:

Сообщение от Dukobpa3 (Сообщение 1002460)
...
- коннектор посылает нотификацию "я получил вот такие данные"
- хостКонтроллер получает эту нотификацию, видит данные, парсит
...

Вот в этом месте может же быть сеттер? Ведь это рассылка точно не многоадресная, и не может предназначаться нескольким модулям, значит событийную модель обмена можно не использовать здесь.
Или "уж если все так, то и этот пусть будет как все"? Или, просто, через фреймворк по другому не получится?

А... или это, чтобы удерживать уровень абстракции?

Котяра 09.06.2011 21:20

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

Dukobpa3 09.06.2011 22:14

Цитата:

Вот в этом месте может же быть сеттер? Ведь это рассылка точно не многоадресная, и не может предназначаться нескольким модулям, значит событийную модель обмена можно не использовать здесь.
Или "уж если все так, то и этот пусть будет как все"? Или, просто, через фреймворк по другому не получится?

А... или это, чтобы удерживать уровень абстракции?
Это просто удобно. Да, у родительского контроллера есть ссылки на дочерние. Но нотификация может предназначаться не дочернему а внучатому какому-то, или еще глубже. Во избежание танцев с бубном "потом" вокруг внуков и правнуков (на которые у главного контроллера ссылок может и не быть) - делаю нотификацию "сейчас".

Та и как Котяра говорит проще ведь сделать список нотификация - хентлер, чем помнить адреса каждого внука и дергать напрямую детей сеттерами.

А вдруг я в дитяти поменяю внутреннею структуру и этого сеттера либо вообще не станет, либо начнет устанавливать что-то другое? - это еще один аргумент в пользу нотификаций-событий.

И не путайте нотификации с событиями. Нотификация это глобальная муть, там своя схема, вникал как-то, но на пальцах долго объяснять. Есть глобальный контейнер в котором регистрируются все контроллеры, и эти контроллеры говорят глобальному контейнеру какие нотификации им удобнее слушать. А контейнер потом получает все нотификации и растусовывает по тем кто на них подписывался.

Т.е. никаких ссылок друг на друга не надо чтоб подписаться на нотификации. Контролер даже может не знать кто ее послал, просто есть факт - получена нотификация - ее надо обработать, всё.


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

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