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

fish_r 09.06.2011 22:34

Да... Спасибо. Надо будет посмотреть как это сделано. Интересно стало :)

Dukobpa3 09.06.2011 22:53

в роботлегсах вообще много интересного)))

Там к примеру еще один паттерн знатный используется Dependency Injection кажись называется))

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

Crazy 09.06.2011 23:13

Цитата:

Сообщение от Dukobpa3 (Сообщение 1002521)
Там к примеру еще один паттерн знатный используется Dependency Injection кажись называется))

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

Суть Dependency Injection как бы не в этом. Суть в том, что обычно класс в конструкторе цепляет к себе всякую фигню какую сам захочет, а в случае DI он создается весь такой счастливый и свободный, а кто-то снаружи сразу же напихивает ему всяческую фигню во все свободные отверстия. Можно и без глобального контейнера.

Котяра 09.06.2011 23:42

Цитата:

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

i.o. 11.06.2011 00:02

Не вижу смысла нагружать контроллер всякой чушью:
Код AS3:

public class Controll extends EventDispatcher
{
...
 
    private var _model:Model = new Model();
 
    ...
    public function get param():Object { return _model.param; }
    public function set param(obj:Object):void
    {
          if  ( _model.param === obj ) return;
          _model.param = obj;
 
    }
...
}

Разве не будет правильно, работать с данными модели через ссылку на нее саму?
Код AS3:

public class Controll extends EventDispatcher
{
...
    ///
    private var _model:IModel = new Model();
 
    /// Model getter
    public function get model():IModel { return _model; }
...
}

ну и далее уже как:
Код AS3:

var myControl:Controll = new Controll();
myControl.model.someParam = "lalala";
trace(myControl.model.someParam);


Crazy 11.06.2011 00:16

Цитата:

Сообщение от i.o. (Сообщение 1002838)
Код AS3:

myControl.model.someParam = "lalala";



Не забываем про Law of Demeter

Dukobpa3 11.06.2011 00:55

Цитата:

Код AS3:

var myControl:Controll = new Controll();
myControl.model.someParam = "lalala";
trace(myControl.model.someParam);


Я не знаю, но мне такая структура претит. Кто бы ни был владелец этого майКонтрола, но какое он право имеет лезть в его модель? Для этого есть тот самый контрол который знает как с его моделью общаться. Я против управления внуками и правнуками вот такими методами.

Другой вопрос что тот кто имеет ссылку на майконтрол может дернуть какой-то из его методов типа: myControl.setParam();

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

etc 12.06.2011 23:05

Dukobpa3, Control не хранит данные и не должен их выдавать композицией на модель.

Dukobpa3 12.06.2011 23:21

Цитата:

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

Склонен думать о неправильной архитектуре если есть такая нужда.

etc 13.06.2011 09:51

Вы сами себе противоречите :)
Не должно быть какой-то внутренней модели, доступ к ней публичный.

fish_r 13.06.2011 10:02

Цитата:

Сообщение от etc (Сообщение 1003280)
Вы сами себе противоречите :)
Не должно быть какой-то внутренней модели, доступ к ней публичный.

ого! а, тогда, какой смысл в контролле вообще?

etc 13.06.2011 10:43

Цитата:

Сообщение от fish_r (Сообщение 1003283)
ого! а, тогда, какой смысл в контролле вообще?

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

Crazy 13.06.2011 12:51

Цитата:

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

Dukobpa3 13.06.2011 13:01

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

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

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

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

etc 13.06.2011 13:57

Crazy, для других контроллеров, очевидно.

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

Crazy 13.06.2011 14:02

Цитата:

Сообщение от etc (Сообщение 1003315)
Crazy, для других контроллеров, очевидно.

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

Откуда такой странный дизайн?

etc 13.06.2011 14:54

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

Crazy 13.06.2011 14:58

Цитата:

Сообщение от etc (Сообщение 1003330)
Почему странный, модель принадлежит основному контроллеру, у дочернего есть ссылка на этот контроллер. При желании, он может взять у основного контроллера как модель, так и другие интересующие данные. Какие данные нужны будут дочернему, основной не знает и знать не хочет, поэтому модель у него в паблике.

Это называется blob antipattern -- когда систему пронизывают хаотичные связи типа "захотел и взял публичные данные". И внесение изменений в одной части вызывает непредсказуемые эффекты по всей системе.

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

etc 13.06.2011 15:02

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

Это всё описание вот этой модели.

Crazy 13.06.2011 15:10

Цитата:

Сообщение от etc (Сообщение 1003338)
Я этого не предлагаю, об основном контроллере и основной модели все дочерние контроллеры знают и у них и так и так есть ссылка на этот контроллер.

Отлично. Пусть знают, если это им нужно. Зачем, кстати?

Цитата:

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

Цитата:

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

etc 13.06.2011 15:16

Цитата:

Сообщение от Crazy (Сообщение 1003340)
Отлично. Пусть знают, если это им нужно. Зачем, кстати?

Основной контроллер как минимум фасад, общающийся с сервером. Ну заодно и основную модель держит.

Цитата:

Сообщение от Crazy (Сообщение 1003340)
Если у них уже есть нужные им данные -- зачем они лезут в чужую модель? Если в их модели нет нужных им данных -- ее неправильно спроектировали. Нужно исправить, пока не поздно.

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

Цитата:

Сообщение от Crazy (Сообщение 1003340)
Какое конкретное свойство этого дизайна не позволяет реализовать описанным мной способом, не лазая в чужие модели? BTW, неоправданное использование нестандартных нотаций мягко говоря не способствует коммуникации.

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

Crazy 13.06.2011 22:58

Цитата:

Никакое, можно и так, просто нет смысла настолько абстрагировать контроллеры.
Смысл состоит в следовании Law of Demeter для минимизации зависимостей. Однако это возвращает нас к моему вопросу, который был фактически проигнорирован:

Цитата:

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

fish_r 13.06.2011 23:24

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

etc 14.06.2011 00:18

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

Crazy 14.06.2011 00:28

Резюмирую: никаких плюсов мы взамен не получаем.

Спасибо за дискуссию.

Dukobpa3 14.06.2011 00:34

У меня для этих целей есть обычно два синглтона:

1. Для каких-то статичных данных (Это например грузим что-то с сервера пачкой, там базовые настройки системы и в таком духе, и вот реально всем они нужны в той или иной мере)
2. Для динамических (У меня это банально bulkLoader)

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

etc 14.06.2011 09:44

Цитата:

Сообщение от Crazy (Сообщение 1003546)
Резюмирую: никаких плюсов мы взамен не получаем.

Спасибо за дискуссию.

Если вам не влом передавать каждый раз ссылки на очевидные вещи, то да, никаких плюсов.

Crazy 14.06.2011 13:00

Цитата:

Сообщение от etc (Сообщение 1003584)
Если вам не влом передавать каждый раз ссылки на очевидные вещи, то да, никаких плюсов.

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

etc 14.06.2011 15:04

Цитата:

Сообщение от Crazy (Сообщение 1003607)
Простите, смысл этой меткой фразы прошел мимо моего сознания. Нельзя ли переформулировать?

К сожалению, нет, потому что я уже всё объяснил.

spirit2 10.08.2011 13:11

Не хватает конкретики для понимания. Тему осилил процентов на 90, а также статьи и другие подобные темы.

Несколько вопросов:
1) Модель диспатчит Event.CHANGE и вьюшка сама разбирается, что конкретно поменялось в модели, или модель генерит конкретное событие "яблоки подорожали", а вьюшка уже отображает новую цену?
2) Вьюшка, слушает события от действий юзера, определяет, что нажата кнопка Play и отсылает контроллеру событие "начало просмотра" (как здесь: http://www.flasher.ru/forum/blog.php?b=348), или вьюшка отсылает событие "меня тут где-то нажали", а контроллер по таргету уже определяет, что раз нажата кнопка с id1, а это кнопка Play, и значит пользователь хочет начать просмотр?
3) Есть таймер. Слушается событие TimerEvent.TIMER, по нему преобразуются значения таймера в понятные юзеру минуты/секунды и отображаются на экране. Отображает понятно вьюшка, а кто должен заниматься преобразованием? Контролер в котором создается таймер и слушается же событие меняет вью (минуя модель), модель в которой слушается событие от таймера созданного в контроллере, а потом диспатчится Event.CHANGE при каждом тике таймера, или вьюшка должна сама слушать от контроллера, преобразовывать и отображать (минуя модель)?

В каком случае более правильное классическое MVC или есть еще варианты? =)

etc 10.08.2011 13:13

1) Обычно конкретное, если модель сложносочиненная;
2) Вьюшка шлёт конкретное событие PLAY_CLICK;
3) Событие таймера слушает модель, в себе содержит время в timestamp, например, при изменении шлёт событие. Вьювер ловит и через форматтер выводит время.

Dukobpa3 10.08.2011 13:22

Цитата:

3) Событие таймера слушает модель, в себе содержит время в timestamp, например, при изменении шлёт событие. Вьювер ловит и через форматтер выводит время.
У меня обычно один из двух вариантов:
1. таймер в контроллере. По таймеру контроллер пихает в модель неформатированное время. Модель говорит что ее изменили. Вьюха форматирует время так как ей надо.
2. опять же таймер в контроллере. Контроллер пихает Форматированное время в модель. Вюшка просто берет готовую строку и отображает.

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

etc 10.08.2011 13:39

Dukobpa3, а я сую таймер прямо в модель, как правило он статический и вещает на все экземпляры моделей.
Нагружать контроллер этой ерундой не вижу смысла, не говоря уже о том, что у меня нет какого-то специального контроллера модели, который занимается её изменением.

Dukobpa3 10.08.2011 13:52

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

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

Добавлено через 6 минут
А то что статический то да, но вот к примеру в текущем проекте у нас есть синглтон с данными пользователя.

Там пара: модель + контроллер.
Соответственно контроллер запускает таймер, а модель хранит в себе неформатированное время. Плюс это время периодически синхронизируется с сервером.

А все вьюхи уже берут эту цифру и показывают кому как надо.

ir73 31.10.2011 11:02

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

Dukobpa3 31.10.2011 11:31

Если можно я отвечу, хоть вопрос и не ко мне)) Так же под шумок возможно кто-то укажет и на мои ошибки в понимании данного вопроса:)

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

Хотя есть вариант реализации и слегка иной, в частности он используется в роботлегс, советую посмотреть. Там все контроллеры на одном уровне и все вьюхи. В момент использования просто берется то или иное из общего пула и вуаля. С самим фреймворком общался сугубо в ознакомительных целях потому тонкостей не знаю, но в целом вроде так.

etc 31.10.2011 11:32

Цитата:

Сообщение от ir73 (Сообщение 1042704)
прикольная тема, осилил-таки наконц полностью, хоть и не за один присест. Много идей интересных.
etc, я так понял, что в твоих проектах может быть несколко триад, в том числе и вложенные. Кто занимается добавлением вьюшек в дисплей лист? Контроллер? Если да, то как ты определяешь, куда контроллер должен добывить свою вью, ведь очень часто ее надо засунуть не просто в документ класс, а в какой-то определенный контейнер, о котором контроллер нечего не знает, а знает только более старшая вьюха.

Старшая вьюха и создаёт.

Dukobpa3 31.10.2011 11:32

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

ir73 31.10.2011 12:36

Цитата:

Сообщение от etc (Сообщение 1042708)
Старшая вьюха и создаёт.

создает да, а добавляет кто (addChild)? контроллер? откуда у него ссылка на какой-то из внутренних displayobject container-ов?

etc 31.10.2011 12:43

Создаёт — это и есть new с addChild. Контроллер построением интерфейса не занимается.
Если это компонент (окно, например), то связыванием контроллера с компонентом занимается какой-нибудь менеджер компонентов. Или же контроллер компонента им же самим и создаётся.


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

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