![]() |
dimarik,вот по твоему опыту на сервер данные слать должна модель?Тут несколько раз возникала идея что это работа для контроллера.По мне так контроллеру вовсе незачем знать кухню модели и протокол общения с сервером.
Вики говорит, что можно и так и так,но предостерегает от «ТТУК» («Толстые, тупые, уродливые контроллеры»; Fat Stupid Ugly Controllers).Интересует твое мнение по вопросу. |
undefined, дружище, пожалуйста, прекращай троллить ).
|
dimarik - моя трактовка вполне как раз нормальна. Ты забываешься, что проекты разные, и каждый работает с разными приложениями и играми. В твоем случае - модель может быть ГЛАВОЙ приложения ( в твоем случае, всмысле в твоих проектах) , в более простых же проектах, модель обычно коробка данных. - Давай рассмтрим простой пример пинг-понга скажем. 2 дощечки и шарик. Вьюха хватает события мыши(клавы) и т.п. проверяет на хитТест попадание шарика, диспатчит ГОЛ, контроллер ловит событие и запускает процесс в моделе типа ГОЛ++. В данной игре кроме как счетчик голов, счетчик SCORE и т.п. в моделе ничего не будет, и да это будет безмозглая коробка данных. Это если по простому, можно конечно начать изврат = и делать модель завязанную на всю логику, в таком простом приложении, это называется too much
По топик стартеру - задавая такие вопросы, которые он задает, рано лезть и писать ММО, а значит ему пока надо научится на простых проектах. Сразу лезть в дебри и настроить себе голову так, что модель это основа - сможет только бывалый, вспомни как ты начинал, у тебя и мыслей таких не было. undefined - учитесь оптимизировать приложения. Если ваш контроллер становится толстым, значит подход неверный. У меня обычно контроллер( base ) кроме как запросы к серверу и получения данных ( + работа с моделью соответсвенно) ничего не делает, в крайнем случае можно дернуть вью из контрола пользуясь MVP - но это обычно ровно столько методов, сколько запросов к серверу. И я опять же не претендую на знание гуру MVC - mvc - он такой, какой тебе надо, а не такой который тебе навязывает то один, то другой, когда голова начинает у некоторых идти кругом. |
in4core, не соглашусь. Уже много раз оговаривалось, что модель — это ядро приложения.
В пинг-понге вью передает контроллеру сообщение о том, что что делает игрок (вьюха сама разруливает, каким именно образом игрок воздействует на смену направления и скорости движения палки). Контроллер эту информацию передает модели, мол, там палку в другую сторону потянули. Именно модель определяет, гол или нет. Если да, модель гавкает об изменении счета или о геймовере. Первое ловит сама вью и перерисовывает табло. Второе ловит контроллер и действует согласно заложенному воркфлоу. Он сообщает вьюхе, чтобы она сворачивала игру и разворачивала сообщение, что игрок продул. От нее же контроллер ждет, что там игрок решил: разбить приставку о стену или таки нажать что-то там (контроллеру на это пофиг — это может быть нарисованная кнопка или хоткей) что означает "давай еще раз!!" |
Други! Сидел, читал с интересом дискуссию профи, а пока созрел ещё вопрос по MVC. В моём проекте (по-прежнему, это игра на механике текстового квеста) всё взаимодействие с пользователем строится через последовательно выводимые ему текста и изображения (всякие шкалы и портреты пока не в счёт). Сейчас это работает так: Модель, делая расчёты, набивает в массив инструкции. Каждый элемент - экземпляр класса-наследника ViewInstruction. Когда посылается событие на отработку этих инструкций, Вью начинает его разбирать, вынимая и анализируя каждый элемент массива вот таким образом:
Код AS3:
Чтобы быть выполненными, экземплярам классов-инструкций требуются на входе какие-то элементы самой главной Вью. Например, инструкция на обновление текста должна получить ссылку на экземпляр MainTextArea и доступ к её пабликам. А инструкции на вывод арта никак не обойтись без ссылки на слой, куда этот арт нужно выводить, плюс какие-то координаты могут потребоваться, которые хранятся в главной Вью. Навскидку, можно было бы запускать из главной вью вот так: Код AS3:
|
Цитата:
|
Цитата:
|
да,резонно
|
Это особенно критически важно в монетизированных клиент-серверных приложениях. Когда нужно, чтобы логика добычи денег обсчитывалась в скрытой модели на сервере. Например в игровых автоматах, вьюшка лишь сообщает о кликах по кнопкам, а контроллер обращается к удаленной модели не сервере, та обсчитывает все по формулам конкретной игры и выдает результат. Который и отображает вьюшка, имитируя бурную деятельность.
С другой стороны, ничего не мешает делать модель по типу перфокарты, если безопасности сильно не требуется. Которая является некими изменяемыми данными, которые мы просто отображаем вьюшкой. И разные вью могут эти данные отображать сильно по разному, имея внутри себя всякую свою разнообразную логику, базирующуюся на данных модели. В общем и целом, соглашусь с in4core - все сильно зависит о задачи. |
ZergMaster - именно об этом я и писал, слово в слово.
Zebestov - дружище, вот ничем не отличается твой пример собственно от моего, лишь тем, что модель решило гол или не гол. Хотя - даже чисто математически смотри - if(sharik.x < 0) dispatchEvnet(gol...) model-> aga gol Это я к тому, что я уже на этапе вью знаю гол или нет, нафига мне передавать каждый раз координаты в модель, или же вообще постоянно апдейтить это на таймере в моделе, чтобы модель узнала гол произошел или нет? Что за злобное рпограммирование? Добавлено через 6 минут Не надо ничего себе усложнять - мвц - это инстуркции к применению, а не злобный смотритель с палкой. Тут 100500 людей, и большинство тем или иным способом юзает этот паттерн - и 100500%, что у каждого он СВОЙ, просто потому, что каждый пишет так, как ему удобно, НООО - есть большое но, есть конечно и нюансы, где перегибать палку не надо, если ты из view.model.method() делаешь - бить по рукам, а если у тебя gfx логика во вью, а модель только сборщик данных ( как это реально работает в слотах ) , а контроллер общается с сервером и напрямую работает с вью по мвп моделе, это не есть ох и ах, это один из методов организации приложения. |
А вот у меня такой вопрос возник. Если например во вьюхе, нужно кликнуть на способность, куда записывать идентификатор этой способности? Чтобы по нажатию кнопки(например "Изучить"), последующий запрос на сервер отправился с этим id. Понятно, что вью не изменяет модель, поэтому модель способности(а именно записать туда кликнутный идентификатор) можно обновить только через контроллер. Что вообще должно отвечать, за запись такого рода вещей? Хотя наверно, для этого надо создать переменную в контроллере, например click_id и если кликнул на способность, получаем её id и записывать в контроллере в click_id, нажали на другую способность, также перезаписываем click_id, а уже отправка на сервер, берем этот самый click_id
|
И кстати, вот интересный момент : у тебя есть свитчер + -. Когда жмется +, счетчик меняется на ++, минус на -- соответсвенно, и это записывается текстовое поле. Кроме того это значение важно и другим вьюхам, по нему они определяют что делать далее. Тоесть значение счетчика, это переменная модели, глобальной допустим. Все вьюхи подписаны на модель и жаждут изменения счетчика, чтобы делать свои дела.
И вот смотрим : жму я +, по парадигме я должен отправить ивент в контроллер из вью, контроллер доложен дернуть модель, модель должна записать данные - а затем и разослать всем. Это на какой то пук кнопки. А вот если я отойду в неком приложении от этой идеи, и лишь в этом месте дерну модель напрямую как model.plus() - я выходит сразу стану балдой и балбесом, и это нифига не МВС, когда все остальное написано без таких вот изварщений? С другой стороны - мы можем сказать, что значение счетчика может быть не переменной модели, а переменной вью, и тогда вопрос снимается, ты из вьюХ баблишь в главный, а он там всем вьюхам рассылает апдейт, но в этом случае у тебя уже вью работает как модель. Тут тонкая грань - какие процессы будут идти в моделе, а какие во вью... Добавлено через 2 минуты Цитата:
|
Цитата:
|
Классический способ реализации метапаттерна MVC описан в вики. Это упрощенная схема работы комплексных (complex — составной) блоков, состоящих из других паттернов. В моей практике все блоки я реализовавал из шаблонов GoF.
От задачи все не сильно зависит, да простит меня камрад in4core... За разработку даже простого пинг-понга я бы не стал браться без моего любимого быстрого инструментария. Обычно я делаю модель на основании технического задания (ТЗ). Никаких вьюх пока еще нет. Как будут выглядеть вьюхи очень слабо представляет себе даже геймдизайнер. И я имею ввиду не только их художественную ценность, а то, что они будут собирать от пользователя. И их либо просто нет, либо кто-то их еще пишет. Зато геймдизайнер обладает формулами и общим видением проекта, чем и делится с разрабом, т. е. мной. Иногда это выглядит как общение на пальцах. И вот, моя модель готова в соответствии с ТЗ и прошла юниттесты. Подтягиваются вьюхи, и приложение собрано и готово себя показать. Приложение может существовать без вью. Они просто заменяются на mock'и. Я рассуждаю о модели в паттерне MVC как о Вселенной: на её физические законы не влияют (но это не точно) наши рассуждения, мнения и вообще наш Homo sapiens разум. Законы природы везде работают одинаково. Законы природы просто есть и они действуют без нашего участия. Неважно в каком диапазоне волн воспринимают визуально мир люди, собаки и кроты. Мы есть только вьюхи в шаблонах Вселенной ). И, кстати, на нас можно давить с помощью Модель в паттерне MVC сама в себе и она самодостаточна. Она получает данные от контроллера, да. И выдает переработанное и осмысленное состояние всем вьюхам, подключенным к этой модели. Если контроллер сказал, что температура за бортом -60°, то модель просто не начнет выращивать курочек для фермы -- слишком холодно. Зато она начнет производство льда в промышленных количествах. По вопросу камрадов Цитата:
Цитата:
Тут нужно пояснение. Данные, находящиеся в модели должны пройти через сериализатор, предназначающийся для конкретной серверной платформы. А возможно и не серверной, если вы просто сохраняете стейт модели в файловую систему. Это существенное дополнение. На самом деле роль сериализаторов и десериализаторов (парсеров) весьма серьёзна. Я видел проект, в котором десериализация данных была в самой модели. Это ставит модель в зависимость от вида внешних данных (JSON, XML, YAML, custom protocol). Не делайте так. Сериализация/десериализация должна быть внешней по отношению к модели и осуществлена с помощью контроллера. Цитата:
Цитата:
|
dimarik - Дим, ну что значит не зависит. Ты рассуждаешь щас и навязываешь, как человек уже покопавшивайся в этом годами, я же тяну другую сторону, я могу с тобой согласится, и скажу - что все что ты говоришь верно, но не надо забываться - что здесь не все люди прошедшие дзен, и могут это осознать сразу, нужны попытки. дела и т.п. *За разработку даже простого пинг-понга я бы не стал браться без моего любимого быстрого инструментария.* это ЩАС ты выпендриваешься, а лет эдак 5-10 назад промолчал бы о своем быстром...хм...инструменте. И про обычно я делаю... мало ли что ты обычно делаешь? Может зубы чистишь. Это сугубо твоя жизненная организация. Ты говоришь каждый раз за СЕБЯ, как делаешь ты - но не объявняешь почему и зачем так делать, это называется я будда и я вам скажу, а почему и как додумывайте сами.
*Обычно я делаю модель на основании технического задания (ТЗ).* ОЛОЛО - даже Ubisoft себе такого не позволят сказать ОБЫЧНО! Ты что создал тонны игр которые весь мир юзает? Чтобы твое обычно было парадигмой? Мало ли что ты делаешь обычно, как бы грубо это не звучало - ! |
Цитата:
|
Цитата:
|
Ты не хочешь признавать, что я привел простой пример, который, как и любой сложный пример, базируется на тех же принципах (противоположных тем, что изложил ты). Именно это постоянство от проекта к проекту и делает MVC удобным — ты всегда действуешь одинаково по сути, разница только лишь в масштабе.
|
Есть два столпа на которых держится этот форум – это MVC и in4core.
А ещё проходят года, а dimarik'а читать всё так же увлекательно. Вспомнилось: Цитата:
Цитата:
Всё толстое – плохо. И толстые модели – плохо, и толстые контроллеры – плохо, и толстые стриптизёрши – тоже плохо. В хорошем коде из контроллеров код мигрирует в модель, а из моделей – уже "куда-нибудь". Чаще всего в то, что общим словом называют сервисы. Таскать паттерны Это, к слову, относится и к MVC. В "классическом" MVC вьюха это эдакая чистая функция от модели (моделей). На деле же, в игрульках, вьюха может иметь достаточно обширное внутреннее состояние, ровно до тех пор пока это состояние никак не влияет на общее состояние приложения. Цитата:
Игра без визуального представления вообще (белый экран) бесполезна. CLI App's вполне себе живёт без вьюх (пайпит потоки в stdin/out/err). Вся идея в том, что всё вместе формирует приложение, эти блоки (M/V/C/VM/whatever) по отдельности – самодостаточные элементы (которые просто тестировать – и в этом, в общем-то, добрая половина всего смысла, но о тестах ты только разок упомянул) бесполезны. Цитата:
Цитата:
Сериализатор (который совсем необязательно работает / дёргается с помощью контроллера) читает модель как вью, но вот пишет в неё как контроллер. Или как часть модели. Вью никогда не может просто взять, и поменять все данные внутри модели "сходу". Кто-то другой может. Цитата:
|
Zebestov:
про вопрос о том,кто должен реагировать на gameover от модели Цитата:
Цитата:
|
Цитата:
События, требующие визуализации актуального состояния, слушает вью. Как-то так. |
Цитата:
а) сколько у тебя контроллеров или он один? б) сколько у тебя моделей? ( если ли общая модель, или же просто разрозненные типа PlayerModel, IFaceModel и т.п. ) в) Что у тебя происходит в иерархии событий и т.п. когда игрок движется вправо-влево, что происходит , когда ловит яблоко? Я как обычно не претендую на гуру, но как по мне в данной игре достаточно всю логику спокойно уместить во вью, а контроллером только посылать на сервер скоре игрока и т.п. , а модели чисто хранить какие то данные, ну и совсем малость где, обновлять вьюху, но это прям 1-2 метода не более. |
Контроллеров несколько, дерево.
Моделей несколько, тоже дерево. Вьюх тоже несколько, и да, опять дерево. Главный контроллер проводит игру по кругу: меню-игра-меню-игра… "от пункта к пункту". Контроллер слушает свою модель и свои контроллеры. Например MainController ждет от MainMenuController событие "CLOSE". Дождался — приложение идет дальше — GameController.open(), предварительно подписавшись на его CLOSE. Тот же GameController в свою очередь слушает от GameModel событие GAME_OVER и решает, что делать дальше, после того, как персонаж "запаркуется" на стартовой позиции (тоже по событию от модели поймет): откатать рекламу, например, или сразу посылать событие CLOSE, чтобы MainController снова открыл меню. Таким образом контроллер(ы) заведуют движением приложения. Т.е. вся логика происходит в моделях. Отображение актуальных состояний реализуют вьюхи с помощью прослушивания событий от моделей. Контроллеры берут на себя рутину — что делать дальше, и когда это делать (дали старт окну закрыться — стоим, курим, ждем завершения анимации, вьюха сообщит когда). Вправо-влево, генерация яблок, падение яблок (формула равноускоренного падения, привязанная ко времени), фиксация улова, когда яблоко ниже уровня корзины (формула, реализующая фиксацию улова не в данный момент, а тогда, когда яблоко пересекло линию, так мы устраняем эффект от лагов) — все это происходит в модели. Кроме отображения информации, важной для игры GameView делает еще вещи, которые вообще не должны волновать ни модель, ни кого-либо другого: анимирует появление яблока из листвы, топает ножками персонажа и т.д. Ну вот условно так. |
мне кажется zebestov достаточно ясно разделил:событие запускает дальнейший флоу?Да - ловим его в контроллере,нет(типа надо просто обновить очки) - ловим во вью.
|
Цитата:
Добавлено через 10 минут Цитата:
Добавлено через 17 минут Цитата:
|
Дима
Цитата:
А двоякое ощущение, потому что ты пишешь слегка непонятно, *все нормально в парадигме* - это значит ты не запрещаешь раз в 100 лет дернуть метод модели из вью? Или ты говоришь наоборот, что парадигма должна быть выполнена как положено, клик вью, пересылка в контрол, пересылка в модель, рассылка всем ??? Добавлено через 1 минуту Цитата:
|
Цитата:
|
Цитата:
Имеется ввиду, что самый ок вариант – это когда есть условный `ISerializator`, который всем этим и занимается. Весь код приложения к нему, по большей части, агностичен. Юзкейс: проверять доступность транспорта до тех пор, пока не найдется лучший. Например: используем [веб]-сокеты, если клиент/платформа может в них. Если нет, то long-polling (это когда HTTP request висит в "ожидании" до тех пор, пока данные не пришли). В первом случае сериализуем в бинарном виде компактненько, во втором – только жирно строками (json/base64/xml/etc). (Конечно, юзкейз требует ещё и `IServerConnector`, которых тоже два – слать в сокет и слать хттп реквесты – суть та же самая) |
Разъяснил как мог:
Цитата:
Десериализация — процесс перевода последовательности битов в структуру данных (via wikipedia). Парсинг, а точнее, синтаксически анализ, это и есть часть процесса десериализации. В случае, если модель будет работать с JSON, то произойдет такая цепочка (вариант 1): 1. Чтение из источника потока байтов (файловая система или сетевой протокол), представляющих собою plain текст, который полностью подчиняется грамматике JSON; 2. Преобразование текста (десериализация и парсинг) в ActionScript Object; 3. Чтение полей из этого Object и заполнение полей конкретного объекта(ов) модели. Второй пункт часто избыточен, поэтому десериализацию можно сделать без него (вариант 2): 1. Чтение из источника потока байтов (файловая система или сетевой протокол), представляющих собою кастомный протокол; 2. Поток по неким правилам анализируется десериализатором, который пишет в поля конкретного объекта(ов) модели. Пример: есть протокол AMF1/3, с помощью которого происходит десериализация данных непосредственно в strong typed объект ActionScript. Однако с помощью него нельзя переписать поля существующего объекта. Десериализация потока этого протокола средствами флеша всегда приводит к созданию новых объектов. Так вот десериализатор из второго пункта "варианта 2" может быть: а) встроен в объекты модели; б) внешним по отношению к объектам модели. Пункт "а" подразумевает, что по мере чтения из потока, некто, анализируя его, извлекает из модели нужный объект и передает в него поток. Этот объект модели последовательно читает из потока нужные ему данные. Предыдущая итерация повторяется столько, сколько есть данных для модели в потоке. Пункт "б" предпочтительнее. Некто извлекает из модели объект и сам пишет в него. Затем повторяет. Этот некто и есть десериализатор, зависящий от конкретного протокола. Именно в нем заложены правила разбора протокола. |
и это все лишь бы не создавать новый объект на каждый респонс?Оно того не стоит имхо.
|
Каждому своё.
|
Да, в этом есть резон, выносить парсер отдельно от модели. Я делал разбор в самой модели, это не очень удобно.
|
Увидел тут мельком, речь зашла о ветвлении Моделей и Контроллеров. Я как раз до этого в своём проекте дошёл. Вот смотрите, есть игра, в ней у героя инвентарь. Его функционирование обеспечивается своей персональной триадой MVC, верно. Когда пользователь жмёт кнопку инвентаря, это событие слушает главная Вью и посылает событие в главный Контроллер. Главный Контроллер создаёт дочерний Контроллер инвентаря, который в свою очередь создаёт Модель и Вью инвентаря. Дальше все манипуляции обрабатываются дочерней MVC, и только событие на закрытие остаётся за главным Контроллером, который, получив его, свернёт всю лавочку и даст команду главной Модели продолжать.
Верно я всё написал? |
Контроллеры создает контроллер. Модели — модель. Вьюхи плодятся во вьюхе.
Ко всем этим дочерним элементам есть доступ по геттеру, например. Триада создается путем создания нового контроллера, который всегда имеет в аргументах как минимум две ссылки: необходимые ему для работы модель и вью. Есть только один контроллер, который создаем модель и вью — это MainController. В нем создаются MainModel и MainView. Больше ни в одном контроллере модели и вьюхи не создаются. Они подаются в конструктор (или метод-инициализатор). |
Цитата:
|
А ты сам как думаешь?
|
думаю,что нет,но древовидность обоих заставляет сомневаться.
|
Ты прав, есть существенное отличие. А древовидность (насколько это возможно) будет, пожалуй в любой реализации. Она призвана исключить горизонтальные связи.
|
Цитата:
Самое главное, что модель одна и она глобальна. |
Друзья, вновь меня терзают сомнения в части MVC. Исходные такие.
В Модели в качестве идентификаторов у меня используются строковые значения. Они объявляются публичными статическими константами и затем присваиваются разным нечисловым свойствам. Возможно, это не оптимально с т.з. использования ресурсов, но очень удобно при отладке, так как такие штуки можно выводить в trace() и сразу понимать, что происходит. При этом я использую те же идентификаторы при обращении к классам пакета language, подбирающим слова и фразы на нужном языке. Это уже работа Вью. Сомнение в том, не нарушаю ли я принципы MVC с таким подходом. Ведь получается, что Вью в таком виде как бы "привязана" к Модели - не функционально, но использованием общих "статических" справочных данных. В качестве альтернативы думаю создать что-то вроде класса-посредника, который загружал бы в Dictionary ID-шники, используемые в Модели, и выставлял бы им соответствия для использования во Вью. В таком подходе есть два выигрыша: во-первых, можно реализовывать отношения "один-ко-многим", когда для нескольких ID может быть одинаковый текст для вывода, и во-вторых, если потребуется какой-то идентификатор поменять (например, чтобы он лучше отражал суть), то будет точное понимание единственного места, где исправить, а не лезть напрямую в языковые xml в десять мест. Ну а минус - в геморрое и усложнении, само собой. Просьба прокомментировать. Спасибо. |
| Часовой пояс GMT +4, время: 15:58. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.