|
|
|||||
MVC: грамотная архитектура проекта
Салют!
Я однажды познакомился с идеей MVC (спасибо Тигре). Тогда все казалось удобным и правильным. Но все мои упражнения в этом направлении ничего хорошего не принесли. Каждый раз модель превращалась в обычный VO, а вся логика делилась межуд видом и контроллером. Метод не самый плохой - мне удавалось сосредоточить данные в одном месте, где их могли подхватить все заинтересованные виды, но от MVC почти ничего не осталось. Не так давно у одного блогера я вычитал утверждение, о том, что если в проекте нельзя вырезать вид и заменить его новым, без каких либо изменений в остальном проекте, тогда архитектура, скажем так, не прошла "MVC-проверку". Это он объяснил на примере игры-шутера: Если у Вас есть грамотно написаный шутер с изометрическим видом (скажем, как у Alien Shooter), тогда просто переписав вид можно сделать из него 3D-шутер (как Wolfenstein 3D). Я пришел к выводу, что теоретически в такую игру можно играть даже без вида - действия игрока передаются в модель через контроллер и в самой модели уже происходит "экшн", а вьюшки нет, значит просто некому это отобразить. После этого я еще раз понял, что мое стремление сделать из моделей просто "говорящие" VO не совсем соответствует парадигме MVC и я в очередной раз решил создать проект с "правильным MVC". Думал-думал и придумал себе проблему: калькулятор то написать в таком стиле не проблема, а тот же шутер - не так просто... Вот Вам ситуация: непрерывная стрельба. Если речь идет о скоростреле, тогда все просто. Кто там успеет посчитать все пули... Модель просто будет генерировать снаряды через определенное количество времени и считать их попадание + урон. А в это время вид будет отображать какое нибудь подергивание оружия да вспишки выстрелов, ну возможно будет еще полоска, имитирующая полет очереди пуль. Попробуй придраться - все выглядит естественно. А теперь меняем свой чудо-автомат на помповое ружье и... Конец халяве! Выстрелы на столько редкие, что так халтурить при их отображении уже не получится Лично я вижу два варианты реализации, но мне они не очень нравятся... 1) Модель знает сколько должен длится выстрел и ей плевать на вид. А вид получает уведомление о выстреле и начинает анимацию вистрела, отдачи, перезарядки, возвращения в исхоное положение. Все круто, но во время сильной нагрузки плеера (в браузере, кроме игры, запущено еще 4 сериала и две социалки с тонной векторной графики и фильтров) звук этого набора действий проиграется без проблем и, скорее всего, синхронно с моделью , а анимация скорее всего будет хромать. 2) Модель делает выстрел и ждет указаний контроллера для следующего выстрела. А контроллер, в свою очередь, ждет известий от вида, что выстрел благополучно закончен и только тогда командует модели "Пли!". Вариант очень красивый, но тогда получается, что модель очень сильно зависит не только от действий игрока, но и от действий вида. К тому же такой подход порождает множество "висячих макаронин" - дыхание модели разбито на вдох/выдох и без разрешения вида, посланное через контроллер, хоть умри, но дишать нельзя. Хотя нет, чтобы умереть тоже нужно разрешение. О как наворотил... Но и это не самая сложная ситуация. В обоих реализациях либо модель либо вид решают сколько должно длиться конкретное действие. А что, если от их воли ничего не зависит. А что, если такое решение принимает сервер - пойди узнай, когда он ответ пришлет. И это все сгенерировала моя скудная фантазия, а что подкинет реальная практика? Бррр... Короче, если заглянет сюда какой нибуть поклонник MVC, очень прошу укажите мне на мои ошибки в рассуждениях и дайте несколько рекомендаций, в каком направлении стоит двигаться. Ато казалось бы парадигма MVC должна упростить какие нибудь аспекты разработки, но "Мое MVC" только создает проблемы на пустом месте. |
|
|||||
elder_Nosferatu есть еще различные подвиды MVC. Я лично использую архитектуру где
Модель - "хранилище данных" и "методы поведения" данной модели Контроллер - создает модели и вьюверы, основная работа связывание активностей между моделями и вьюверами. Вьювер - получает модель и отображает её В таком случае, я бы написал следующее. Контроллер вызывает в модели метод Выстрел из точки А в точку В ракетой. Модель генерирует событие - "выстрел" и записывает в массив "летящие_снаряды" характеристики данного выстрела ( точка А,Б, тип оружия, скорость движения) Вьювер получив от модели событие выстрел, получает массив снарядов, по надобности добавляем проверку что-бы не отображать одни и те же снаряды несколько раз, соответсвено получает характеристики этого снаряда и отображает полёт.
__________________
return this... |
|
|||||
Блогер, вообщем-то, всё верно написал.
В моделе, вам необходимо описать 2 разных типа оружия. Оба оружия должны наследовать абстрактный базовый класс всех орудий, например - AGun. В базовом классе - есть методы, необходимые всем орудиям, но конкретную реализацию определяет конкретный наследуемый класс. В базовом классе, вы добавите курок - onFire. В наследуемом классе, этот "курок" Может автоматически переходить в положение false после выстрела, или ждать внешнюю команду "отжатия" - в зависимости от типа оружия. Соответственно, модель игры ведёт огонь, если курок нажат, и не ведёт, если он отжат. Всем этим заправляет модель, задача контроллера лишь - дёргать этот курок. Контроллер не должен описывать сам процесс выстрела, эта элементарная задача лежит на моделе. Вообще, все элементарные задачи, должна решать сама модель. Такие как: перемещение физического тела юнита в мире, перезарядка оружия, нанесение урона объекту, если в него попала пуля.. Задача контроллера - более глобальная, он выдаёт приказы, управляет действиями ИИ: юнитА -> переместиться в точку B, юнитБ -> вести огонь по противнику. А элементарное выполнение приказа - лежит на моделе. Ей решать, как конкретный тип юнита будет выполнять этот приказ. Что-бы легче понять, представьте себе, что модель - это описание мира со всеми его законами. Модель описывает гравитацию, и она же её применяет ко всем объектам в мире. Контроллер же - лишь манипулирует этим миром, создаёт новые объекты, указывает объектам, что они должны сделать. Но как именно это сделают объекты - это решает модель, в соответствий с её законами. Если объект падает в лаву - модель без чьего-либо разрешения - уничтожает этот объект. Ведь в соответствий с её законами, объекты не имеющие флаг "read-only" - уничтожаются в лаве. И конечно, модель высылает событие уведомления о печальной участи объекта. В визуализаторе архитектура построения отображения - идентична модели. Во вью есть абстрактный базовый класс для всех орудий - AViewGun, все наследуемые классы, самостоятельно определяют, как им отображать их тип оружия. Как может выглядеть ситуация с выстрелом из дробовика: Любое оружие в игре, (AGun) имеет курок: onFire (курок нажат/нет). Конкретный класс дробовика, наследует AGun. Далее, дробовик при каждом шаге игры сам проверяет - если его перезарядка выполнена (оружие может выстрелить) и нажат его курок - он стреляет, устанавливая затем новую паузу перезарядки. Внешний код - может 500 раз нажать на курок, но сам выстрел произведёт только дробовик, когда его удовлетворят все условия.
__________________
Дети не должны знать о своих родителях Последний раз редактировалось Tails; 30.09.2013 в 18:18. |
|
|||||
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
AlexCooper Вы обошли стороной вопрос автора. Если следовать Вашей логике, то имея в руках автомат и нажав пять раз кнопку, вью передаст контроллеру пять кликов, тот передаст модели пять кликов, модель рассчитает сколько пуль выпущено за каждый клик и передаст пять массивов во вью. И все работает, так же как и сказал автор, но если такой подход применить к дробашу, то когда пользователь так же нажмёт пять раз, то модель получит пять массивов с редкими выстрелами дробаша.
Но а вдруг пользователь судорожный и пока один выстрел не закончил нажал ещё сто раз и побежал, то получится, что пока он бежит дробаш будет стрелять. |
|
|||||
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Оффтоп - вчера сделал виток в обучении в сторону этого шаблона и точно так же со вчерашнего дня не могу решить одну проблему. модель не чего не говорит контроллеру, который имеет связь с сервисом. как модель может сказать сервису, что ей нужно больше данных?
|
|
|||||
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Цитата:
Добавлено через 12 минут AlexCooper Вы не сочтите мой короткий вопрос - "Кому", за дурной тон. Просто мне уже раз обьясниле, что если контроллер подписан на модель это не mvc.. |
|
|||||
@Tails
Судя по Вашему примеру с дробовиком, Вы вообще отвергаете мой 2-рой вариант реализации выстрела (модель заявляет о начале выстрела и ожидает известия от контроллера, что вид закончил отображение выстрела). По моему этот вариант дает возможность синхронизировать поведение модели с отображением этого поведения, Но все же меня просто бесит то, что модель ждет разрешения на продолжение деятельности от вида. К тому же такой подход сильно прибавляет в коде: модель расказала виду, он некоторое время это отображает и докладывает контроллеру о завершении, а ток уже командует модели "давай, расказывай дальше". Каждый набор последовательных действий порождает целый вихрь из евентов... Даже если бы это был ТРУ-МВЦ, я бы не стал так делать - просто заворот мозгов! Но все же меня не покидает мысль о том, что может возникнуть ситуация, когда последнее слово будет за видом... |
|
|||||
Akopalipsis Из материалов википедии
Цитата:
Добавлено через 1 минуту elder_Nosferatu модель никого никогда не ждёт. Она живёт своей жизнью.
__________________
return this... |
Часовой пояс GMT +4, время: 11:08. |
|
« Предыдущая тема | Следующая тема » |
|
|