Форум 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=214735)

ZergMaster 22.03.2018 12:16

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

Appleman 22.03.2018 14:43

ZergMaster, само собой. Так и сделано. Есть пакет data, в котором живёт класс, например, CharacterIDs. Но в него лезут как классы Модели, так и Вью. Мой вопрос, является ли использование общих ID-шников Моделью и Вью нарушением принципа взаимной независимости элементов MVC?

Zebestov 22.03.2018 14:53

Да какая же тут может быть зависимость?! Если все в курсе, какие общие термины используются в приложении, доступ к механизмам они от этого автоматически не получают.

Appleman 22.03.2018 20:33

Zebestov, спасибо. Понял-отстал.

Zebestov 22.03.2018 22:42

Нене, ты не отставай, спрашивай ) я сам поначалу заморачивался по каждому поводу.

Appleman 08.05.2018 01:18

Друзья! В соседней теме обсуждали, как asset-ы для игры загружать. Пока у меня для этого в AssetManager-е есть Dictionary, где хранятся и отдаются по строковым ID BitmapData графики: для главного героя (ГГ), локаций, врагов и т.п. Соответственно, пачки картинок должны загружаться или удаляться в определённые моменты. В частности, картинки для ГГ - при выходе из интерфейса создания своего персонажа, картинки для локации - момент захода в локацию и т.п.

Вопрос №1, кто в MVC командует этим процессом и дёргает паблики Asset-менеджера? Например, текущая локация у меня - это свойство ГГ (экземпляр Character). Если игрок выбирает опцию "сменить локацию" и попадает в другую, в модели персонажа свойству _location присваивается новое значение. Тут же по идее должно отправляться событие, по которому нужно давать отмашку Asset-менеджеру грузить картинки. Вопрос, кто должен ловить это событие: сам Character, Модель, Вью?

Вопрос №2 в продолжение. Если картинки ГГ должны загружаться сразу после создания персонажа (и оставаться в быстром доступе до самого конца игры), то я решил сделать на будущее пакет heroCreation и какой-нибудь примитивный класс, который потом будет реализовывать полноценный процесс создания ГГ для игрока. И вот о чём я задумался. По уму для создания ГГ должна быть своя триада MVC. Значит, кто-то должен её создать. А у меня это сделать некому. Подскажите, как должны выглядеть Модель, Вью и Контроллер самого верхнего уровня? Я так понимаю, в данном вопросе вариантов немного, есть некий канонический вид.

Спасибо.

ZergMaster 08.05.2018 11:59

Цитата:

Сообщение от Appleman (Сообщение 1205137)
Вопрос, кто должен ловить это событие: сам Character, Модель, Вью?

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

Цитата:

Сообщение от Appleman (Сообщение 1205137)
Значит, кто-то должен её создать. А у меня это сделать некому.

это как? 0_о :eek:

Appleman 08.05.2018 14:24

Цитата:

Сообщение от ZergMaster (Сообщение 1205145)
странный вопрос.. событие оно на то и событие, что поймать его могут все, у кого есть экземпляр. А могут не ловить. В том плане, что кому надо, тот и должен. Насколько я понимаю, в данном случае модель чарактера, которую уже слушает вью чарактера.

Ну не то чтобы все, а только те, у кого ссылка есть на объект, посылающий это событие. Пораскинув мозгами, склоняюсь к мысли, что отдавать команду грузить картиночки - точно не удел Модели. Так что либо Вью, либо Контроллер.

Кстати, даже до события можно. Если игрок выбирает опцию "сменить локацию", но об этом первым "узнаёт" Вью, потом Контроллер. Возможно, кто-то из них уже может скомандовать asset-менеджеру начинать загрузку с диска?

Цитата:

это как? 0_о :eek:
Это так, что я как начал писать кусочек, связанный непосредственно со сражением, так у меня при запуске программы сразу же и начинается заруба :) В Main написано буквально следующее: new battle.Battle(_view, _hero, _enemy, _location). Это создание контроллера. В нём:

Код AS3:

public function Battle(host: MainView, player:Character, enemy:Character, location:Locations):void
                {
 
                        _host = host;
 
                        var foregroundCharactes: Vector.<Character> = new Vector.<Character>;
                        foregroundCharactes.push(player);
                        foregroundCharactes.push(enemy);
 
                        _model = new BattleModel (foregroundCharactes, location);
                        _view = new BattleView (_model, _host);
                        _host.addChild(_view);
 
                        _view.addEventListener(ViewEventsIDs.MENU_SELECT, menuCommandHandler);                                        // Подписываемся на выбор меню
                        _view.addEventListener(ViewEventsIDs.INSTRUCTIONS_LOADED, ClearInstructionsArray);        // Событие обработки массива состояний
 
                        _model.init();
                }

Теперь вот понимаю, что надо сверху-вниз начинать. Ранее в теме был совет, что каждый из элементов триады MVC сам создаёт своих "дочек". Я и спросил, как должны выглядеть главные Контроллер, Модель и Вью для всего приложения.

Добавлено через 3 часа 29 минут
Скажите, а прочитавшим эту тему от корки до корки ачивку на форуме дают?

Tails 08.05.2018 22:04

Цитата:

Сообщение от Appleman (Сообщение 1205148)
Скажите, а прочитавшим эту тему от корки до корки ачивку на форуме дают?

Можно :)

Appleman 10.05.2018 19:08

В плане оффтопика скажу, что получил искреннее удовольствие от чтения той самой темы. Интересно было наблюдать, как нынешние гуру, каждое слово которых моментально отливается в граните, каких-то 6-8 лет назад мечутся и дискутируют на предмет удачных (а по факту зачастую и неудачных) подходов. В частности, Psycho Tiger или Zebestov, проходящий путь от Контроллера к Модели...

Закончил с лирикой, конкретизирую вопросы. Люди, по всей видимости, тут уже шарахаются, видя много текста от меня. Дам вместо него ссылку. Гляньте плиз вот это сообщение, оно как раз по моей теме. Я правильно понимаю, что то, что советовали для реализации дочерних Контроллеров/Моделей - это "второй вариант"?

У меня в голове как-то плохо умещается взаимодействие элементов триады MVC, если каждый из них САМ создаёт своих дочек. Правильно я последовательность себе представляю:
1. Главный Вью создаёт дочерний Вью. В главном пишем геттер для дочернего. В дочернем пишем сеттер для дочерней Модели.
2. Главная Модель создаёт дочернюю Модель и к ней также геттер.
3. Главный Контроллер из главного Вью забирает по геттеру дочерний Вью, а также из главной Модели ссылку на дочернюю Модель и создаёт дочерний Контроллер, передавая в его конструктор ссылки на дочерние Модель и Вью. Дочернему контроллеру есть на что подписываться (связка "V-C") и чем командовать (связка "C-M").
3. Наконец, дочерний Контроллер, уже имея ссылку на дочернюю Модель, просто устанавливает её для дочернего Вью через сеттер. Дочерний Вью подписывается на дочернюю Модель, "закрываю" последнюю связку "M-V". Всё готово.

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

И ещё вопрос. Нормально, когда Модель вообще одна, а разные Контроллеры появляются в комплекте с разными Вью по необходимости?

Zebestov 10.05.2018 19:37

В принципе стройненько все вышло, кроме одного момента:

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

ZergMaster 11.05.2018 12:21

Цитата:

Сообщение от Appleman (Сообщение 1205185)
Нормально, когда Модель вообще одна, а разные Контроллеры появляются в комплекте с разными Вью по необходимости?

Нормально. Просто не слишком удобно, если более-менее большой проект. У меня, как правило, главная модель является Фасадом для более мелких. Важно не делать лишних телодвижений, не делать "ООП ради ООП" - сначала делать одну модель. Как только видишь, что она превращается в небольшую портянку (больше двух экранов) - значит надо её декомпозировать и прятать в Фасад. Лучше, конечно, все это делать на этапе проектирования, но не всегда это удается. Это как с наследованием - функционал выносится в абстракции только тогда, когда в этом наступает необходимость.

Appleman 12.07.2018 17:01

Друзья!

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

Понятно, что для карты/боя/магазина - свои Вью. Вопрос в том, как лучше реализовать общие компоненты. Рассматриваю варианты:
1. через наследование - создать Вью с общими компонентами и методами доступа к ним, а все остальные Вью наследовать от неё, тем самым делая эти методы также доступными. Тогда неважно, где игрок провёл очередной игровой час: в бою или в борделе - время обновится.
2. делать независимым классом, который будет подписываться на Модели карты/боя/магазина и вылавливать то, что касается обслуживаемых компонентов.

Что думаете?
Спасибо.

ZergMaster 13.07.2018 12:34

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

Appleman 02.10.2018 15:29

Друзья, ситуация:

1. Имею в Модели слот экипированного персонажу объекта (не обязательно предмет). Сам такой объект имеет свойства и статусы, отображаемые во Вью. Их состав может меняться в зависимости от типа;
2. При изменении свойств/статусов экипированного объекта Модель посылает событие, Вью по нему обновляет: выводит иконки рядом с окном экипированного.
3. Когда объект удаляется из экипированного, то работает следующая логика: если этот объект относится к самому персонажу (например, руки), то все статусы скрываются в окне экипированного и одновременно выводятся в окне персонажа, уже рядом с его портретом. А если экипированный объект - это предмет, то ничего никуда не нужно выводить.

Основанием для обновления Вью является событие от Модели. Сейчас оно приходит только при изменении значений свойств объектов. Поэтому при смене экипированных объектов события отправлены не будут, т.к. никакие их свойства не изменились. ДУмаю, как реализовать нужное мне поведение. Есть 3 варианта, но ни один мне не нравится:

1. На уровне Модели проверять, что за объект имеем и либо принудительно посылать соответствующие события в момент, когда он удаляется из экипированного, либо нет. Гарантированно даст нужный результат, но в моём понимании, нарушает принцип MVC, т.к. с т.з. Модели, совершенно по фигу, какие объекты как будет отображать Вью.
2. Сделать паблик в классе экипируемых объектов типа forcePropsRecheck(), который будет повторно посылать события на обновления Вью. Во Вью проверять, что за объект удаляется из экипированного и при необходимости дёргать этот паблик-метод. Тоже будет работать, но вроде как вмешательство в Модель со стороны Вью, хотя с т.з. состояния Модель не меняется. Только события переотправляет.
3. Всегда посылать события на обновления свойств и статусов экипируемого объекта из Модели: что при добавлении , что при удалении. Во Вью усложнять алгоритм обработки этих событий и по месту разбираться, что за объект, экипирован он или уже снят и т.д. Такой подход выглядит как самый правильный с т.з. принципов MVC, но самый геморройный.

Просьба прокомментировать. Спасибо.

ZergMaster 04.10.2018 12:59

коментирую: ничиво не поняль...
Вот где-то здесь мозг отключается полностью:
Цитата:

Поэтому при смене экипированных объектов события отправлены не будут, т.к. никакие их свойства не изменились
Можно как-то на примере?

Appleman 04.10.2018 14:58

Да, пардон, я так и понял, что никто ничего не понял. Если честно, то я пока формулировал здесь в форуме, уже сам допёр, но всё равно было бы интересно увидеть комментарии.

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

Теперь игрок убирает кинжал. При выполнении соответствующего действия Модель посылает событие об изменении экипированного объекта, Вью убирает изображение кинжала и выводит изображение голых рук. При этом иконка "отравлено" должна пропасть и более нигде не выводиться.

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

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

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

ZergMaster 04.10.2018 16:57

А в чем проблема? Вроде как модели без разницы, что там во вью. В модели хранятся состояния экипировки: "голые руки", "кинжал", "без рук". У состояний, в свою очередь, есть свойства "отравленный", "ледяной", "огненный". То есть берем "кинжал", смотрим в свойства, видим, что он "отравленный" - тогда вью отображает иконки. Так же любые другие свойства. Если же это свойство не экипировки, а персонажа, то они висят все время в другом месте. Таким образом, например, присвоение "голым рукам" свойства "отравленный" может автоматически присваивать это же свойство персонажу.
Или я что-то не так понял

Appleman 05.10.2018 10:01

Да, примерно так. Главная сложность была в том, что Вью требовались разные действий для разных типов владельцев одного и того же свойства.

Разумеется, весь алгоритм определения и отлова был создан во Вью.


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

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