Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   MVC: грамотная архитектура проекта (http://www.flasher.ru/forum/showthread.php?t=203620)

Akopalipsis 30.09.2013 23:19

KumoKairo Спасибо! я её как раз и читаю, мне очень нравится стиль, которым описывают все шаблоны.

Tails 30.09.2013 23:22

Цитата:

Сообщение от elder_Nosferatu (Сообщение 1147381)
@Tails

Столько написал, что даже смогу более конкретно описать проблему.
Получается, что если длительность какого либо действия зависит от длительности анимации или звука, тогда это значение нужно записать в модель, как параметр и просто засекать нужное время в тот момент когда виду подается команда на отображение/озвучку. Но тогда нужно полностью отказаться от родной покадровой анимации. В случае тормозов длительность кадра/кадров может сильно увеличится, но таймеру на это плевать. Значит анимацию нужно прокручивать вручную с расчетом прошедшего времени. Я правильно понял?

В конечном счёте, применяемая методика зависит от целей конкретной задачи. Нет решения, которое бы подошло в 100% случаях всем.
  • Конечно, для мп3 плеера, отдельно задавать время воспроизведения трека было-бы не разумно, гораздо выгоднее прослушивать сам мультимедиа файл. Этим мог-бы бы занимался соответствующий контроллер.
  • Для анимационного окна интерфейса в игре, хорошим решением будет предоставление ему управляющих событий, которые оно могло бы использовать, информируя внешний код о тех или иных действиях пользователя. В этом случае, контроллер подписанный на это окно, будет принимать дальнейшие решения.
  • Для игрового процесса, все действия должны быть описаны в моделе: перезарядка, регенерация, всё это - относиться к логике игрового процесса и просто не может быть завязано на каких-то там анимациях. В этих случаях, анимация подстраивается под модель, а не наоборот.

Цитата:

Сообщение от Wolsh (Сообщение 1147385)
После выстрела дробовик перезаряжается (во вью) и юзер НЕ МОЖЕТ выстрелить в этот момент. Какая разница, сколько времени длится перезарядка? Юзер сможет снова выстрелить, только когда она закончится. Так при чем тут модель? С какого перепугу она-то должна стрелять, пока юзер не нажал "выстрел"? А он не может нажать, пока идет перезарядка. Модели даже знать не надо таких параметров как скорострельность и т.п., она просто получает от контроллера "юзер нажал выстрел" и считает последствия, меняет кол-во патронов в обойме и считает нанесенный ущерб. Это ДАННЫЕ. А остальное — забота вьюхи. Да. "Может ли вот сейчас выстрелить дробовик" это забота вьюхи. Все что ей надо для этого от модели — это кол-во патронов.
Что я думаю не так?

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

Кто ещё из нас советует "толстый контроллер" ?

Wolsh 30.09.2013 23:53

Цитата:

Таким образом, вы с успехом засовываете всю логику и половину модели дробовика во вью
Это очень важный вопрос — что является логикой. Посылать ли событие "выстрел", если юзер нажал клавишу в момент перезарядки оружия — это логика? Его нажатие НИЧЕГО НЕ МЕНЯЕТ в игре. Данные Модели здесь никоим образом не должны изменяться. Никакого события нет. Никакой "логики" на уровне Модели здесь не требуется.
"Засунуть всю логику" было бы рассчитать полет пули и ее попадание в противника прямо во Вью (где есть все координаты), а для Модели посылать только событие "враг получил пулю, проверьте как он там".
"Вытащить всю логику" означает каждый пиксель полета пули брать из Модели, и каждый кадр предсмертных судорог, и каждый кадр процесса перезарядки (ну, а что еще такое "таймер в модели", по-вашему?) Вам то не кажется, что Вы пихаете Вью в Модель?
Весь вопрос стоит на том, что именно считать данными. Есть ли какие-то данные в том, что юзер нажал курок во время перезарядки? Зачем это Модели? Это вопрос чисто интерфейса игры с пользователем. Зачем Модели подтверждать выстрел? Вью не справится с тем, стрелять или нет, на основании данных (из Модели!) о количестве патронов в обойме и текущего состояния анимации дробовика? (готов к выстрелу/не готов)? Зачем конкретно Модели знать, готов к выстрелу дробовик или нет? На какие данные/логику это может повлиять, кроме как "реагировать на событие ЮзерНажал, или нет, если вдруг это событие придет"? Так вот придет ли событие, это вопрос интерфейса, то есть Вью.

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

вам таки придётся разделить логику, отображение и данные на отдельные составляющие
Простите, но ЛОГИКА не может существовать без ДАННЫХ. Держать логику в контроллере означает сделать из Модели гулящую девку, готовую отдавать все что попросят, а не только нужные для отображения конечные результаты(!) вычислений; означает обеспечить связку контроллер-модель сотней геттеров или проще уж тупо делать все её данные публичными. Это ООП?
Контроллер является ключевой фигурой в парадигме MVC. Вот только не потому, что является мозгом приложения. А потому, что именно он обеспечивает суть концепции MVC — разделение данных и отображения. Не будь контроллера, мы бы писали модель для конкретной вью и вью для конкретной модели. Только и всего. Контроллер призван собрать в себе всю эту конкретику. Он знает язык Вью и знает язык Модели. И "язык" здесь не просто как перевести слово. Он переводит СМЫСЛ, потому что смыслы для Вью и для Модели разные. Контроллер должен понимать смысл событий Вью для Модели. Иначе все вью будут вынуждены изначально писаться для этой конкретной модели, а модель — понимать, что ей делать при "юзер нажал клавишу Р".

Tails 01.10.2013 00:35

Да, наш с вами разговор ни к чему не приведёт, пока мы обсуждаем реализацию некоторой абстрактной, не оговорённой конкретно задачи. Вы представляете её по своему, я по своему. Меня только задело, что вы не сильно придерживаетесь концепций MVC (как мне показалось):
  • Перезарядка дробовика - на мой взгляд, это несомненно логика.
  • Скорострельность - тоже логика.
  • И даже количество патронов в обойме это - логика, относящаяся к под-модели оружия.
Перенос и просчёт этих параметров в виде - слишком уж грубое нарушение концепций MVC (в моём представлений задачи). Возможно, вы представляли себе нечто иное и потому допустили такое перемешивание.

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

Цитата:

Простите, но ЛОГИКА не может существовать без ДАННЫХ. Держать логику в контроллере означает сделать из Модели гулящую девку
Верно. Под логикой - я имел ввиду контроллер верхнего уровня. Поясню:
В одном из сообщений в начале, я описывал, как модель (М) - вполне имеет внутреннюю логику, описывающую её базовое поведение, или "правила игры", или "общие законы игры". Сюда входят все просчёты столкновений, нанесение урона, лечение, перезарядка дробовиков и все прочие общие элементы.
Контроллер верхнего уровня (С) - занимается тем, что влияет на эту модель. Он помещает туда новые дробовики, нажимает курки, добавляет мобов.

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

Цитата:

Контроллер должен понимать смысл событий Вью для Модели. Иначе все вью будут вынуждены изначально писаться для этой конкретной модели, а модель — понимать, что ей делать при "юзер нажал клавишу Р".
Цитата:

Сообщение от Tails (Сообщение 1147374)
В визуализатор может помещаться слушатель пользовательского ввода, который будет регестрировать клики мышкой, ввод с клавиатуры и прочие действия игрока. Затем, слушатель их минимально обрабатывает - (нажата кнопка включения двигателя, нажата кнопка стрельбы) Эти данные считываются контроллером и уже он принимает какие-то конкретные действия. Слушатель помещается во вью только потому, что от-туда ближе всего доступ к устройствам ввода.


Wolsh 01.10.2013 01:42

Цитата:

реализацию некоторой абстрактной, не оговорённой конкретно задачи
Мне казалось, вопрос вполне понятен. Возможно, я все упрощаю, конечно.
Цитата:

Перезарядка дробовика - на мой взгляд, это несомненно логика.
Это изменение данных о количестве патронов в дробовике и в рюкзаке. Эти числовые данные (даже не логика, уж простите) нужны для сейва, для отображения в HUD и окнах инвентаря и торговли. Состояние дробовика (я ведь правильно понимаю, что под "перезарядка дробовика" Вы имеете в виду временное состояние, когда стрелять из него нельзя?) нужно только для определения, будет ли иметь место событие "выстрел", когда юзер нажмет клавишу. Тут ровно ноль данных для Модели, это данные исключительно для интерфейса. Если очень хочется, Вы конечно можете хранить эти "данные" в модели и посылать события "дробовик начал перезарядку", "юзер нажал", "юзер снова нажал", "дробовик закончил перезарядку". Прикол в том, что, пошлете Вы эти события и будете хранить и менять состояние дробовика в Модели, или нет — в игре ничего не изменится. Это логика интерфейса на том же уровне, как "может двигаться ползунок слайдера дальше по х или нет". Ваш вариант — послать в модель события "ползунок достиг максимального значения", "юзер пытается двигать ползунок", "юзер всеравно пытается двигать ползунок", "о, перестал". Мой — посылать в Модель события "значение слайдера изменилось. новое значение 15%". Сравните, где есть информация, интересная для Модели.
Цитата:

Скорострельность - тоже логика
Как параметр оружия это — данные. Данные для логики? Например, да — для функции сравнения в инвентаре и торговле. Ой, кажется сравнение интересно только юзеру, а в Модели никаких данных не меняет? Чисто подсветить, выделить. У одной вью это есть, у другой нет, ибо только отвлекает. Модель от этого не меняется НИКАК, кроме того же самого случая, когда Вы зачем-то решите хранить в модели "подсвечиваем АК-47 как более скорострельный чем текущее помповое", как будто эта подсветка хоть как-то влияет на игру. А ведь у другой Вью, позвольте, этого нет? Что же, мы храним в Модели какие-то данные СПЕЦИАЛЬНО ради одного фриковью? А может это вью само позаботится о своих фриках?
Как параметр для определения частоты автоматической стрельбы, при зажатой клавише, когда второй и последующие события "выстрел" происходят не от нажатия юзером клавиши, а пока он не отпустит нажатую клавишу. Ну, отлично. Посылаем события "выстрел" с нужной частотой. Модель их получает и проверяет кого убили. И меняет кол-во патронов. А время то между выстрелами ей зачем считать и сообщать об этом Вью??? Что это за данные такие? Событие "выстрел" это команда от юзера. Это никак не результат размышлений Модели.
Цитата:

И даже количество патронов в обойме это - логика, относящаяся к под-модели оружия.
Во-первых, это все-таки данные (но я рад, что Вы прониклись содружеством данных и логики). Во-вторых, кол-во патронов это единственные данные, которые я во всех своих сообщениях помещал в Модель, так что не знаю, кого Вы тут оспариваете))).
Цитата:

Перенос и просчёт этих параметров в виде - слишком уж грубое нарушение концепций MVC
Не всё то данные, что может быть измеряно. Есть миллиарды данных, абсолютно ненужных игре (логике). У каждого объекта есть полсотни свойств, никак не влияющих ни на какие действия и вычисления. Не надо Модели хранить все это барахло и дергаться при каждом изменении чего-то, интересного ТОЛЬКО ТОМУ, кто изменился.
Цитата:

Меня только задело, что вы не сильно придерживаетесь концепций MVC (как мне показалось)
Я не придерживаюсь концепций MVP, в которой модель это неподвижный ящик с ячейками, хранящий все подряд и открытый настежь, вью — такая же неподвижная картинка, каждый кадр берущая слепок с модели, в которой хранятся все данные О ВЬЮ, а контроллер содержит весь гений РНР-программиста, при каждом движении юзера (или даже при каждом кадре?) дергающий модель за все сиськи, чтобы вытащить из нее данные, обработать их и запихать в нее обратно через сотни геттеров и сеттеров. На фоне этого даже одно из базовых положений MVC "модель извещает [вью] о своем изменении" выглядит какой-то бессмысленной шуткой — зачем, если именно контроллер все посчитал и вот он, держит все эти изменения в руке? Зачем лишние связи? Ведь Вью могла бы не знать о Модели вообще ничего, общаясь только с контроллером, который итак уже имеет доступ ко всем данным Модели (а заодно и сотни "своих" переменных для временного хранения копий этих данных для рассчета)? Откуда же взялись эти события апдейта модели? Да просто классический (тонкий) контроллер НЕ ИМЕЕТ доступа к данным модели, потому и передать их вью — не может. Это логика MVC. В MVP я не вижу никакой логики, только подстраивание под технические особенности веб-программирования: отношения БазаДанных - СерверныйСкрипт - БраузерКлиента, которые невозможно трансформировать в MVC технически — все это в разных местах и на разных языках. MVP это попытка насколько возможно натянуть концепции MVC на эту ситуацию. А РНР-шники сегодня, наверное, составляют бОльшую часть всех программистов планеты?)) и дружно верят, что это "правильный MVC", даже не задумываясь, что сделать все как-то по-другому в их ситуации просто невозможно. Это не концептуальное, это технически неизбежное деление. И даже в нем, как ни верти, а у всех свистелок и перделок их собственная "логика" находится во вью, в виде какого-нибудь джаваскрипта. Никому не приходит в голову создавать и отслеживать на сервере и хранить в базе данных каждую падающую снежинку на новогодней странице.

elder_Nosferatu 01.10.2013 05:16

Такой маленький дробовичек, а сколько текста из-за него! Наверное удачный пример подобрал для холивара ;)

@Wolsh
Сейчас объясню зачем данные о дробовике пихать в логику. Напомню с чего все началось:
Цитата:

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

Так вот, если таким макаром реализовать стрельбу, тогда игрок нажмет кнопку один раз и будет ожыдать, что стрельба не будет прекращаться до тех пор, пока он эту кнопку не отпустит или пока не закончились патроны. И выброс отстреляной гильзы/подача следующего патрона и перезарядка магазина - тоже части однокнопочного действия "СТРЕЛЬБА". По этому для логики процесса будут важны и скорострельность и количество патронов в магазине и их количество в кармане, а может и еще какие нибудь данные...

А в остальном Вы заставили меня задуматься... Да и не меня одного, я уверен!
Благодарю за умственную пищу. Буду размышлять.

Wolsh 01.10.2013 10:43

А это я о чем?
Цитата:

Как параметр для определения частоты автоматической стрельбы, при зажатой клавише, когда второй и последующие события "выстрел" происходят не от нажатия юзером клавиши, а пока он не отпустит нажатую клавишу. Ну, отлично. Посылаем события "выстрел" с нужной частотой. Модель их получает и проверяет кого убили. И меняет кол-во патронов. А время то между выстрелами ей зачем считать и сообщать об этом Вью??? Что это за данные такие? Событие "выстрел" это команда от юзера. Это никак не результат размышлений Модели.
Добавлено через 21 минуту
Еще раз, конспективно.
Вы считаете, что выстрел должна инициировать Модель, я — что Вью.
В Вашем случае необходимо пихать в Модель точное время анимации выстрела. То есть для такой Модели нужна СПЕЦИАЛЬНАЯ Вью, в которой анимация выстрела занимает точно такое время, которое установлено в Модели.
Теоретически, наверное можно научить вью растягивать и сжимать анимацию в соответствии с требуемым временем. Это Вы, конечно, не сочтете "логикой, которую пихают во вью". А логику "интерфейс сам решает, когда в нем произошло событие", Вы принять ну никак не можете?))) Удачи же.

alexcon314 01.10.2013 11:11

Я как-то не совсем уловил суть дискуссии. Или таки речь идет об этом?
Нужно вынести стрельбу, в отдельную реализацию MVC.
ТС убедил всех, что стрельба - достаточно сложный процесс сам по себе с одной стороны (и это так, и речь может идти не только о стрельбе), с другой стороны, как справедливо заметили другие участники, он он не должен требовать каких-то сверх усилий по обслуживанию, не должен впиливаться в общую канву настолько, что потом не выпилишь). С третьей стороны )), хотелось бы все-таки как-то унифицировать его, подсовывя разные параметры в какую-то более менее общую реализацию.
Представляется такой алгоритм:
юзер взял оружие, создается MVC для стрельбы: модель заполняется данными о боезапасе и пр., вью отрисовыает собственно дробовик (или что там для стрельбы у нас?), ожидает "пли" от юзера, и готов отрисовать перезарядку, пламя и полет, котнтроллер их пасет и отсылает нужные для общей логики игры события в "главный MVC": боезапас уменьшился... пуля летит там-то... и т.п. Существует это все пока юзер не бросит дробовик и не возьмется, например, за ложку, чтобы пообедать. Прием пищи - тоже сложный процесс. Тогда вступает в действие "MVC приема пищи" и т.п.
Т.е. детализация процесса (стрельбы) выносится из общей логики в отдельны модуль, подпрограмму, если хотите. Тем самым, мы сможем предоставить кучу реализаций процесса (стрельбы) без изменений в мэйн-классах, у которых как бы и так забот своих есть. В то же время, мы имеем простор в плане самой реализации, MVC-же.
То же самое можно сказать и по всевозможным диалогам.

Wolsh 01.10.2013 11:57

Алекс, тут проблема в том, что и при организации "дробовик это отдельное MVC дробовика" (что само собой правильно) вопрос синхронизации никуда не пропадает. Если, конечно, MVC дробовика это MVC.
Заявленная сложность в том, что на анимацию выстрела требуется время. Если выстрел инициируется из модели на основании ее данных о скорострельности оружия, то Вью придется рисовать четко под эту конкретную модель, либо проставить в Модели данные, взятые на основании анимации во Вью. Такой MVC попахивает не MVC, а вероятность рассинхронизации из-за фпс остается в деле. Ну, я попытался предложить MVC решение, заключающееся в том, что события интерфейса (выстрел) посылается интерфейсом (то есть Вью) — в соответствии с его собственным циклом анимации. Это же собственное событие Вью.
Однако тут есть неприятность, что числовые данные в модели о скорострельности, как харастериктика оружия для показа и сравнения, так и остаются зависимыми от анимации во Вью.

alexcon314 01.10.2013 13:16

Цитата:

Ну, я попытался предложить MVC решение, заключающееся в том, что события интерфейса (выстрел) посылается интерфейсом (то есть Вью) — в соответствии с его собственным циклом анимации.
Я как бы за.


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

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