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

expl 25.03.2011 01:14

Снова MVC: контроллеры мелких объектов
 
Допустим, делаю фермоподобную игру.
Уже на не первом проекте замечаю рост неподдерживаемой условной логики в общем для всех мороковок, животных и строений контроллере.

Собственно, понятно, что:
- базовая модель "карта фермы" содержит дочерние модельких мелких объектов (2-5 типов)
(ничего не делает, только помогает в получении всякой информации и рассылает события)
- главный контроллер
а) забирает данные от сервера, наполняет и меняет соответствующим образом "карту фермы"
б) принимает данные от кликов по объектам карты и меняет соответствующим образом модель и ее мелкие объекты
с) считает время созревания/протухания/сбора каждого объекта, изменяя в нужный момент модель
- вьюшка
слушает модель, передает события действий пользователя контроллёру

А вот что не понятно:
как избавить контроллер от слежения за всеми типами всех объектов?

- перенести логику в модель?
не получится:
а) Например при заходе к другу действия от пользователя надо обрабатывать по другому
б) В зависимости, от выбранного инструмента нужно по-разному реагировать на действия пользователя
с) Ну логику для разных типов мы разделим, зато загадим мелкую модель жуткой логикой для разных ситуаций

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

- наделать по контроллеру на модельку?

идея нравится, но вот как это сделать?, ведь требования такие:
а) контроллер должен считать и помнить что он насчитал для своей модельки;
б) решать какие действия доступны для его модельки;
с) приводить вьюшку в соответствие с возможными действиями (заставлять всякие значки "скликни меня" рисовать)

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

Есть какие-нибудь идеи?

Gaen 25.03.2011 02:35

Цитата:

Контроллер должен помнить что он насчитал для своей модельки
Если контроллер это помнит, то зачем тогда модель?

Цитата:

Контроллер должен приводить вьюшку в соответствие с возможными действиями (заставлять всякие значки "скликни меня" рисовать)
Если контроллер меняет вьюшку, то зачем тогда модель?

Цитата:

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

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

Как используется поведение:
- Контроллер обращается к методам поведения по ссылке (динамическое связывание)

При смене состояния:
- Контроллер обращается к фабрике поведений, передавая туда новое состояние
- Фабрика получает состояние и отдает соответствующее ему поведение
- Контроллер запоминает полученное поведение как текущее

Скорее всего, поведению потребуется ссылка на модель. Ее можно либо передавать в каждый метод (в таком случае поведение можно вообще сделать статическим классом), либо в конструктор объекта (через фабрику).

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

ShockWave512 25.03.2011 04:01

ох не для всех игр подходит MVC, совсем не для всех
долго там думать надо, чтоб архитектура более менее подходила к "тяжелой" игре

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

примерно можно описать как типизированные массивы Vector.<IData>, Vector.<IModel>, Vector.<IVisual> (скорость) ...
каждый уровень обрабатывается желательно одним, и ОЧЕНЬ желательно маленьким обработчиком/контроллером (скорость) ...
при обработке уровня не трогать другие уровни (скорость)
и ессна не в каждом кадре, в каждом кадре можно только апдейтить анимацию из IVisual, да и то избегать
события от сервера ставить в очередь и т.д. и т.п.

в общем там куча действий по оптимизации, в схему МВС оно все вписывается тяжко, и обычно жутко мешает

хотя бы самую тяжелую часть надо из МВС вытаскивать, делать одним VIEW

Psycho Tiger 25.03.2011 10:27

Цитата:

ох не для всех игр подходит MVC, совсем не для всех
Это типичное заблуждение )
Может быть, Вы имели ввиду "MVC не самое лучшее решение для некоторых игр"?

@expl, я не очень понял в чем загвоздка, но могу порекомендовать бабблинг. =)
Смысл в том, что по клику на однотипные объекты рассылается бабблинг событие. Контроллер ловит это событие и может стянуть модель у вьюшки, по event.target.

expl 26.03.2011 14:51

2 GAIKER:
Цитата:

Если контроллер это помнит, то зачем тогда модель?
Может быть вы и правы. Но сложно сделать контроллер вообще без состоняния не загадив модель.
Цитата:

Если контроллер меняет вьюшку, то зачем тогда модель?
Например морковка должна подсвечиватся, если ее можно сорвать и не подсвечиваться, если нельзя - следить за действиями вроде не обязанность модели.
Или более сложный пример - выбираем место для посадки, таская морковку по всему полю - нам что, при этом модель менять? А если еще какая сложная подсветка ячеек при этом понадобится?
Цитата:

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

Но смущает 2 вещи:
как хранить связь модель-контроллер? (например для карты контроллеры свои, для како-го нибудь магазина - свои, т.е. для каждой подсистемы связь своя)
влепить ссылку в модель? - как-то не очень.

Небольшой оффтоп по поводу связи вьюха - модель: Как по модели найти вьюху?
Я тупо завожу хеш-таблицу в главной вьюхе, содержащей морковки и получаю так: _viewByModel[model].
Вьюха хранит ссылку на модель напрямую. Это нормально, или кто-то нашёл более вменяемый способ?

Цитата:

Можно сделать один контроллер для всех морковок, который хранит их модели в массиве, и тоже реализован по описанной выше схеме. Я бы сделал именно так.
Это если мы выращиваем только морковки, а есть еще редиски, свеклы и животные - для них в этом общем контроллере веточки if-ов растут как на дрожжах.

2 ShockWave512
Цитата:

ох не для всех игр подходит MVC, совсем не для всех
Если он не подходит для такой простой и типичной ситуации - на что он вообще годится?

Цитата:

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

2 Psycho Tiger
Цитата:

@expl, я не очень понял в чем загвоздка, но могу порекомендовать бабблинг. =)
Смысл в том, что по клику на однотипные объекты рассылается бабблинг событие. Контроллер ловит это событие и может стянуть модель у вьюшки, по event.target.
И баблинг у меня есть и модель вьюшка контроллеру передает - беда в том что контроллер один на все типы моделей

Gaen 26.03.2011 17:51

Цитата:

Например морковка должна подсвечиватся, если ее можно сорвать и не подсвечиваться, если нельзя - следить за действиями вроде не обязанность модели.
Или более сложный пример - выбираем место для посадки, таская морковку по всему полю - нам что, при этом модель менять? А если еще какая сложная подсветка ячеек при этом понадобится?
Подсветка ячейки - это ведь чисто вьюшная реакция, она не запускает какую-то логику в контроллере, меняющую модель. Юзер берет морковку, контроллер прописывает в модель состояние "выбор места для посадки", вью ловит изменение модели и "отображает" его, вешая на MouseOver метод подсветки.

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


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

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