Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Статьи (http://www.flasher.ru/forum/forumdisplay.php?f=101)
-   -   Хорошее MVC (http://www.flasher.ru/forum/showthread.php?t=138349)

Zebestov 16.01.2012 21:11

fish_r, ты действительно не сказал ничего, что оспаривал бы Dukobpa3. Особенно легко в этом убедиться, прочитав пропущенный тобой комментарий прямо над твоим возражением.
Вы об одном и том же разными словами :)

fish_r 16.01.2012 21:34

Я его и не пропустил. Мы обсуждали другую частность:

Цитата:

Сообщение от Dukobpa3 (Сообщение 1057123)
Цитата:

Сообщение от fish_r (Сообщение 1057121)
Модель не должны интересовать координаты объекта.

В данном случае координаты это часть модели карты, поэтому они в модели быть должны.


Zebestov 16.01.2012 21:47

Ясно. И как это
Цитата:

координаты это часть модели карты, поэтому они в модели быть должны
противоречит этому
Цитата:

Задача модели, вообще-то, хранить логику независимо от вьюера, то есть ваше приложение должно одинаково работать и с вьюером, и с двумя (выполненными в разных масштабах, например) и вообще без него, напр. в консольном режиме...
Координаты юнита на карте разумеется должны храниться/изменяться в модели (вы оба придерживаетесь схемы, где модель — это данные и логика по их обработке). Вьюха может быть чем угодно (2D, 3D, забавным мультиком, диаграммой посещаемости "храма" юнитами за отчетный период, и т.д.). И модели до этого нет никакого дела. Она живет своей жизнью.

А вот это действительно лишнее:
Цитата:

Модель не должны интересовать координаты объекта.

fish_r 17.01.2012 01:24

Цитата:

Сообщение от Zebestov (Сообщение 1057327)
А вот это действительно лишнее:

Вот это вот действительно лишнее.

Хорошо. Предположим вы делаете не игру, а польз. интерфейс заносите ли вы координаты кнопок в модель?

Zebestov 17.01.2012 01:29

Цитата:

Сообщение от fish_r (Сообщение 1057366)
Хорошо. Предположим вы делаете не игру, а польз. интерфейс заносите ли вы координаты кнопок в модель?

Ну и на этот вопрос тебе Dukobpa3 уже давал ответ, с которым я согласен
Цитата:

Если же это будут координаты какой-то там звездочки которая выпадает откуда-то как некий эффект, то конечно ее координаты никому кроме вью не понадобятся.
Юнит — не кнопка. Юнит — фигурант логики приложения. Кнопка — кликабельный кусок монитора.

Dukobpa3 17.01.2012 02:07

@Zebestov - Спасибо, наверное))) Мои слова поняты верно и с первого раза, плюс за поддержку.

@fish_r - Слушай что тебе старшие говорят ;-Р

HardCoder 17.01.2012 02:15

Интересует взаимосвязь модели с вью. Вьюшка не может изменять модель. Но у нее есть ссылка на модель, соответственно... сами понимаете что. Акцессоры здесь не подходят, так как контроллер должен изменять те же свойства, которые читает вью. В отдельный пакет вьюшку тоже не закинешь. Понятно, я не собираюсь в представлении как-то менять модель :). Но интересно на будущее, просто чтобы уж "совсем правильно", как здесь быть?
Если создать событийный класс для событий модели (имею в виду "пользовательское событие" по К.Муку). В этот класс при диспатче из модели передавать все доступные параметры для вьюшки. Это будет правильно?

Добавлено через 2 минуты
Или лучше создать несколько таких событийных классов, погрупировав в них лишь те свойства, которые непосредственно будут нужны при поимке этого события в представлении?

Zebestov 17.01.2012 02:19

Цитата:

Сообщение от HardCoder (Сообщение 1057381)
...при диспатче из модели передавать все доступные параметры для вьюшки. Это будет правильно?

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

Dukobpa3 17.01.2012 02:21

Цитата:

Вьюшка не может изменять модель. Но у нее есть ссылка на модель
да

Цитата:

Если создать событийный класс для событий модели
Как вариант прокатит, и даже более того это будет один из самых правильных вариантов но сложен в реализации. Сложно будет сделать адекватный рендер с обработкой всех событий и слишком легко запутаться.

Цитата:

Акцессоры здесь не подходят
Очень даже подходят. Просто вью ничего не меняет в модели, только читает всё что ей нужно. А контроллер может еще и менять. Технически это разделить сложно, хотя можно, там придется неймспейсы прикручивать. Я на практике просто сам сознательно не трогаю модель из вью и всё.

Т.е. получается модель продиспатчила - меня изменили. Вью полезла посмотрела нужные данные и всё.

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

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

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

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

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

HardCoder 17.01.2012 02:31

Цитата:

Сообщение от Zebestov (Сообщение 1057383)
Ей даже не важно, кто и каким образом поменял эти значения (модель сама там что-то насчитала, контроллер что-то там вызвал, с сервера данные подоспели).

Это понятно. Я же не говорю что она должна знать кто что менял.
Цитата:

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

Жаль что не правильно. Яхотел просто вьюшку подписать на события модели и больше модель в ней вообще не трогать. Что-то типа этого:
Код AS3:

model.addEventListener(ModelEvent.UNIT_ACTIVATED, activateUnit);
private function activateUnit(e:ModelEvent):void {
      trace(e.activeUnit);
}

То есть, чтобы за свойством activeUnit не лезть в модель с которой по-пьяни можно сделать что-то, а получить его прямо из событийного обьекта ModelEvent.
Что же, будем делать "правильно". Спасибо :)

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

Сообщение от Dukobpa3 (Сообщение 1057385)
Сложно будет сделать адекватный рендер с обработкой всех событий и слишком легко запутаться..

Не совсем понял. У меня какбэ все просто. Есть класс ModelEvent, на события которого подписываются две вьюшки, вернее одна вью - и компьютер(АI). Они получают такие события от модели. Отправляют в контроллер события OpponentEvent.

Dukobpa3 17.01.2012 02:42

Код AS3:

model.addEventListener(ModelEvent.UNIT_ACTIVATED, activateUnit);
private function activateUnit(e:ModelEvent):void {
      trace(e.activeUnit);
}

Это только одно событие получается. Юнита активировали. А будет еще пачка, юнит походил, юнит атакует, юнит копает, юнит в доме.

И это в итоге может разрастись на пачку всего остального.
К тому же если юнита активировали то подсветится те клетки куда можно пройти, а юнит не может ходить по камням к примеру. Так вот в каждом таком событии передавать всю карту нецелесообразно, нужно чтоб вью сама полезла в модель и прочитала параметры карты и потом нарисовала подсвеченные клетки.

HardCoder 17.01.2012 02:46

Цитата:

Сообщение от Dukobpa3 (Сообщение 1057394)
Так вот в каждом таком событии передавать всю карту нецелесообразно, нужно чтоб вью сама полезла в модель и прочитала параметры карты и потом нарисовала подсвеченные клетки.

То что я и хотел узнать!!!

fish_r 17.01.2012 03:23

Цитата:

Сообщение от Dukobpa3 (Сообщение 1057378)
@fish_r - Слушай что тебе старшие говорят ;-Р

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

Dukobpa3 17.01.2012 03:24

Никогда не оценивал возраст по годам, сорри.

fish_r 17.01.2012 03:26

Цитата:

Сообщение от Zebestov (Сообщение 1057367)
Ну и на этот вопрос тебе Dukobpa3 уже давал ответ, с которым я согласен

Юнит — не кнопка. Юнит — фигурант логики приложения. Кнопка — кликабельный кусок монитора.

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

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

Сообщение от Dukobpa3 (Сообщение 1057401)
Никогда не оценивал возраст по годам, сорри.

Блин, а как его ещё можно оценивать? Вы просто непрерывно открываете для меня "новые горизонты".

Dukobpa3 17.01.2012 03:28

Цитата:

Т.е. если один изменил местоположение кнопки, то и у других оно должно изменится.
ключевые слова вот.

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

Добавлено через 58 секунд
Цитата:

Блин, а как его ещё можно оценивать? Вы просто непрерывно открываете для меня "новые горизонты".
Сложный философский вопрос, не для этого форума.
Изначально про возраст как бы шутка была. Но если уж так серьезно то так.

fish_r 17.01.2012 22:32

Вадим не отписался, предположу, что он и в этом, вашем ответе с вами солидарен.
Так вот:

Цитата:

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

Таким образом мы и получаем правильное взаимодействие элементов: вью интерпретирует данные модели,
контроллер интерпретирует данные вью - получаем обособленность, независимость модели от представления (но не обратную, что MVC и не предусматривает).

И, вот что... устал я что то от этого, с вашего позволения закроем прения по этому вопросу.

"Имеющий уши да услышит, имеющий глаза да увидит..."

Dukobpa3 17.01.2012 23:47

Ни к чему ведь прения.
Вы опять же привели один из частных случаев.

Одни и те же шахматы можно сделать как с сохранением истории - тогда ключевым моментом будет порядок действий. А можно хранить только текущее состояние. Тогда достаточно будет только координат фигур на доске.

Оба варианта имеют место быть и на определенном уровне абстракции абсолютно идентичны.

fish_r 18.01.2012 00:01

Прение - это спор. В этом нет ничего страшного )

Ну, ладно. А почему именно координаты вам нужно сохранять (про шахматы)? Можно ведь сохранить в
двухмерном массиве вида x\y, где каждый эл-т это клетка шах. поля. Так нельзя сделать?

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

Dukobpa3 18.01.2012 00:05

Цитата:

двухмерном массиве вида x\y, где каждый эл-т это клетка шах. поля. Так нельзя сделать?
Да как угодно можно. Главное принципы соблюсти.
Касательно шахмат зачем мне целый двумерный массив из 64-х клеток если я обойдусь одномерным массив на 32 значения. Экономия на спичках, в данном конкретном случае, но всё же. И даже если это будет не 8х8, а некое произвольное поле то вьюхе будет достаочно узнать размерность(два значения) и опять же один одномерный массив юнитов.
И разговор наш начинался с карты и юнитов. Тут абсолютно та же ситуация - координаты минимальное чем можно обойтись для воссоздания текущей ситуации.
А вот например есть игра Торибаш. Физика трехмерная, две регдольных куклы файтинги устраивают. Так вот тут нужен именно порядок действий с самого начала боя, так как тут играет роль физика, и очень влияет на исход боя не только текущее положение, а еще и инерция которую мы получили в предыдущих ходах.

Еще может быть какая-то стратегия, чтоб риплеи сохранять и прочее. Ну так ведь это уже другая задача совершенно. К ней и подход другой. Да и тут можно кучу вариантов найти. Либо порядок действий каждого пользователя, либо же набор "скриншотов" модели.

fish_r 18.01.2012 04:00

Цитата:

Сообщение от Dukobpa3 (Сообщение 1057586)
Да как угодно можно. Главное принципы соблюсти.

Вот именно "как угодно" нельзя именно потому, что надо принципы соблюсти.


Цитата:

Сообщение от Dukobpa3 (Сообщение 1057586)
Касательно шахмат зачем мне целый двумерный массив из 64-х клеток если я обойдусь одномерным массив на 32 значения. Экономия на спичках, в данном конкретном случае, но всё же. И даже если это будет не 8х8, а некое произвольное поле то вьюхе будет достаочно узнать размерность(два значения) и опять же один одномерный массив юнитов.

MVC не решает задачу - упросить приложение, оно решает задачу - отделить представление от логики. Так
что если вам понадобится в 50 раз больше усилий приложить, будьте добры приложите их. Иначе не "крестите" свою конструкцию MVC, только и всего.

Цитата:

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

Еще может быть какая-то стратегия, чтоб риплеи сохранять и прочее. Ну так ведь это уже другая задача совершенно. К ней и подход другой. Да и тут можно кучу вариантов найти. Либо порядок действий каждого пользователя, либо же набор "скриншотов" модели.

2Dukobpa3. А кто вам вообще сказал, что непременно должна быть реализована MVC? Что других способов
писать приложение уже не осталось? Это единственный возможный вариант строения приложения? Да, наплюйте, как наплевали на это больше половины (наверняка) игроделов.

Да. Реализация этой парадигмы может привести к значительному усложнению приложения, росту нагрузки,
замедлению быстродействия и пр. Ещё раз - MVC не решает эти проблемы, она решает совершенно другое, так, что взвесьте, подумайте нужно ли вам в очередном приложении такая реализация? Может дешевле будет переделать логику когда потребуется переделывать отображение? Если вообще потребуется.

Но если вы ставите логику в зависимость характеристик отображения, то это не MVC.

Dukobpa3 18.01.2012 23:16

Цитата:

MVC не решает задачу - упросить приложение, оно решает задачу - отделить представление от логики.
Зато я, как программист, решаю задачу упростить приложение и сократить кол-во трафика и внутреннего и наружного. И если я могу это сделать, не нарушая принципов - то я сделаю. Сократить кол-во информации вдвое просто потому что записал не клетки, а юнитов - да запросто. Использовать обратную польскую запись чтобы отказаться от скобок и лишнего форматирования - опять же только за?

Логика от этого не страдает абсолютно, равно как и парадигма МВЦ, а идти заведомо каким-то сложным путем, если можно проще, смысла не вижу никакого.

И вы мне покажите хоть один источник информации в котором указано каким именно образом должны записываться данные в модель? Формулы какие-то? Правила? Их нету.

incvizitor 28.06.2012 17:05

Цитата:

Сообщение от etc (Сообщение 1003545)
Crazy, хаоса никакого, просто в 90% случаев контроллеру нужна так или иначе основная модель, для получения прототипов или иной ерунды, поэтому она по умолчанию идёт линком у родительского контроллера и всё тут. Я опираюсь на собственный опыт (а я считаю, что он уже достаточен) и минимизация зависимостей вот как раз в таких случаях — простое помешательство на MVC, выливающиеся в геморрой по передаче 100500 параметров, вот и всё. Да, можно всё сделать по фен-шую, только незачем и никому это не нужно.

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

etc 28.06.2012 17:12

Цитата:

Сообщение от incvizitor (Сообщение 1086420)
А каким образом лучше организовать получение прототипов из основной модели? И еще, как лучще всего получать их в дочерних моделях?

Реализовать промежуточный класс с ленивым геттером основной модели. Так называемый ассет основной модели. Всё, кто в неё попадает, может получить на неё ссылку. Ну а оттуда уже к коллекции прототипов и т. д.

Dukobpa3 28.06.2012 17:15

Я в базовый класс модели вставляю сылку статическую на основную(серверную) модель.

Psycho Tiger 28.06.2012 17:20

А что такое "прототипы" в этом контексте?

etc 28.06.2012 17:25

Цитата:

Сообщение от Psycho Tiger (Сообщение 1086425)
А что такое "прототипы" в этом контексте?

Прототип — описание характеристик сущности. Своего рода класс сущности.

incvizitor 28.06.2012 17:28

Ага, спасибо. Только что такое "ленивый геттер" ? :rolleyes:

А еще вот в swiz, была такая фишка, всё что попадает на сцену проижектывается автоматом. С этой фичей мы избавляемся от маппинга, но за то приобретаем плюся ДИ. Может быть такую систему можно заюзать для того что бы дочерние модели получали то что нужно?

etc 28.06.2012 17:33

Цитата:

Сообщение от incvizitor (Сообщение 1086427)
Ага, спасибо. Только что такое "ленивый геттер" ? :rolleyes:

А еще вот в swiz, была такая фишка, всё что попадает на сцену проижектывается автоматом. С этой фичей мы избавляемся от маппинга, но за то приобретаем плюся ДИ. Может быть такую систему можно заюзать для того что бы дочерние модели получали то что нужно?

Ну прям выдерну пример ленивого геттера:

Код AS3:

/**
 * @private
 */

private var _user:UserData;
 
public function get user():UserData {
        if (!this._user || !this._user.contains(this)) {
                this._user = null;
                var parent:DataContainer = super.parent;
 
                while (parent) {
                        if (parent is IUserAsset) {
                                this._user = (parent as IUserAsset).user;
                                break;
                        }
 
                        if (parent is UserData) {
                                this._user = parent as UserData;
                                break;
                        }
 
                        parent = parent.parent;
                }
        }
 
        return this._user;
}

Хотя в случае с глобальной моделью, уже инжект:

Код AS3:

/**
 * @private
 */

private var _universe:UniverseData;
 
public function get universe():UniverseData {       
        return this._universe;
}
 
[Exclude]
public function set $universe(value:UniverseData):void {
        if (this._universe == value) return;
        if (!value) this.removedFromUniverse();
        this._universe = value;
        if (value) this.addedToUniverse();
 
        if (this is DataContainer) {
                var dc:DataContainer = this as DataContainer;
                var num:int = dc.numChildren;
 
                while (num --> 0) {
                        var child:Data = dc.getChildAt(num);
                        if (child is IUniverseAsset) child['$universe'] = value;
                }
        }
}


dimarik 28.06.2012 17:45

Зачем this._user = null?
Код AS3:

if (!this._user || !this._user.contains(this)) {
                this._user = null;


incvizitor 28.06.2012 17:50

1 - Понял, спасибо.
2 - А почему бы просто не слушать DataBaseEvent.ADDED?

dimarik 28.06.2012 17:50

И еще. Можно вышестоящим родителем сеттить user, если он у него есть, конечно. Т.е. не обращаться к родителю, а он все сам сделает. Аха, да, это инжект и есть.

Psycho Tiger 28.06.2012 17:53

Цитата:

Сообщение от etc (Сообщение 1086426)
Прототип — описание характеристик сущности. Своего рода класс сущности.

А для чего он может понадобится?

etc 28.06.2012 17:56

Цитата:

Сообщение от dimarik (Сообщение 1086432)
Зачем this._user = null?
Код AS3:

if (!this._user || !this._user.contains(this)) {
                this._user = null;


Я от тебя такого вопроса не ожидал :)

Добавлено через 55 секунд
Цитата:

Сообщение от Psycho Tiger (Сообщение 1086436)
А для чего он может понадобится?

Для хранения общих свойств, типа названия предмета, ссылки на картинку и т. п. Т. е. если у тебя есть однотипные предметы в инвентаре, у них всех ссылка на один и тот же прототип.

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

Сообщение от incvizitor (Сообщение 1086433)
А почему бы просто не слушать DataBaseEvent.ADDED?

А зачем тратить на это время, если никто не обращается к геттеру?

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

Сообщение от dimarik (Сообщение 1086434)
И еще. Можно вышестоящим родителем сеттить user, если он у него есть, конечно. Т.е. не обращаться к родителю, а он все сам сделает.

Можно, но опять же, зачем тратить на это время, если юзер прям вот щас не нужен.

incvizitor 28.06.2012 18:02

Хм, разве это дорогостоящая операция?

etc 28.06.2012 18:07

Цитата:

Сообщение от incvizitor (Сообщение 1086442)
Хм, разве это дорогостоящая операция?

Вполне себе да, особенно учитывая, что оно всплывающее.

dimarik 28.06.2012 18:09

if (!this._user...
this._user = null;

Он вроде и так null;

incvizitor 28.06.2012 18:11

@dimarik, не обязательно.
@etc, ок спасибо.

etc 28.06.2012 18:11

Цитата:

Сообщение от dimarik (Сообщение 1086432)
Зачем this._user = null?
Код AS3:

if (!this._user || !this._user.contains(this)) {
                this._user = null;


А если выполняется вторая часть условия?

dimarik 28.06.2012 18:13

Цитата:

Сообщение от etc (Сообщение 1086438)
Можно, но опять же, зачем тратить на это время, если юзер прям вот щас не нужен.

Ну а если юзер сменится? Нужен апдейт по детям тогда.


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

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