MVC
От: Crystalizer Украина  
Дата: 05.09.07 15:22
Оценка:
Здравствуйте, знатоки паттернов

Вопрос по паттерну MVC.
1) MVC — это паттерн или совокупность двух паттернов типа слушатель и ... ?
2) Вид и Контроллер создаётся извне или Моделью? Или это вообще всё равно?
Как я понимаю внешний класс создаёт модель, вид, контроллер и регистрирует вид в модели, и контроллер в виде и в модели.
Это правильно?



05.09.07 19:24: Перенесено модератором из 'Java' — Blazkowicz
Re: MVC
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 05.09.07 15:53
Оценка:
Здравствуйте, Crystalizer, Вы писали:

В поиск.
Re: MVC
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 07.09.07 12:19
Оценка:
Может быть поможет быть ...
http://rsdn.ru/forum/message/2566219.1.aspx
Автор: Stormblast
Дата: 30.06.07
Re[2]: MVC
От: dolor Китай  
Дата: 14.09.07 05:46
Оценка:
Здравствуйте, Stormblast, Вы писали:

S>Может быть поможет быть ...

S>http://rsdn.ru/forum/message/2566219.1.aspx
Автор: Stormblast
Дата: 30.06.07


наблюдая картинку на одном из приведенных ресурсов,
решил задать давно волнующий вопрос, который, как мне кажется, ни один из виденных мною мануалов по MVC в явной форме не раскрывает:

как с точки зрения MVC выглядит такое:
есть Model, в которой содержится данное — int someData;
есть View1 — окно с Кнопкой, View2 — диалог с полем для ввода текста и View3 — окно с картинкой

событие нажатия на кнопку во View1 ловится Листенером (который является контроллером).
По нажатию на кнопку someData должен увеличиться на 1 и если он окажется больше 10, то должен быть показан View3, если нет то View2.


Первое, что приходит в голову, это такой листенер:
model.increaseSomeData();
if (model.getSomeData()>10)
   showView3();
else
   showView1();

что является вроде как плохим ООП — нарушается принцип tell don't ask, листенер лезет в интимные подробности модели, нарушая инкапсуляцию,
можно и нужно ли по-другому?
Re[3]: MVC
От: KolanT  
Дата: 14.09.07 06:30
Оценка:
D>Первое, что приходит в голову, это такой листенер:
D>
D>model.increaseSomeData();
D>if (model.getSomeData()>10)
D>   showView3();
D>else
D>   showView1();
D>

D>что является вроде как плохим ООП — нарушается принцип tell don't ask, листенер лезет в интимные подробности модели, нарушая инкапсуляцию,
D>можно и нужно ли по-другому?

Можно. Контроллер делает только это:
model.increaseSomeData(); //То есть изменяет модель.

Как только в модели произошли изменения она сама уведомляет об этом.
Это уведомление получают все View.

В View3 будет подобный код:
if model.getSomeData()>10 then
  Show;


В View1 будет подобный код:
if model.getSomeData()<=10 then
  Show;


А реализовывается это с пом Observer'а например...
Re[4]: MVC
От: dshe  
Дата: 14.09.07 06:34
Оценка:
Здравствуйте, KolanT, Вы писали:

KT>Как только в модели произошли изменения она сама уведомляет об этом.

KT>Это уведомление получают все View.

KT>В View3 будет подобный код:

KT>
KT>if model.getSomeData()>10 then
KT>  Show; 
KT>


KT>В View1 будет подобный код:

KT>
KT>if model.getSomeData()<=10 then
KT>  Show;
KT>


Угу. и логика выбора view разбросана по всем view.
--
Дмитро
Re[4]: MVC
От: MaximVK Россия  
Дата: 14.09.07 08:48
Оценка:
Здравствуйте, KolanT, Вы писали:

KT>В View3 будет подобный код:

KT>
KT>if model.getSomeData()>10 then
KT>  Show; 
KT>


KT>В View1 будет подобный код:

KT>
KT>if model.getSomeData()<=10 then
KT>  Show;
KT>



А что будешь делать, если во View7 появиться код вида: if model.getSomeData() > 5 then Show;
Логика выбора view должна быть в одном месте. Мне больше импонирует помещение такой логики в контроллер.
Можно эту логику поместить и в родительскую View, которая будет подписана на событие SomeDataChanged, но это, имхо, не самый правильный ход.
Re[3]: MVC
От: IB Австрия http://rsdn.ru
Дата: 14.09.07 09:16
Оценка: 1 (1)
Здравствуйте, dolor, Вы писали:

D>что является вроде как плохим ООП — нарушается принцип tell don't ask, листенер лезет в интимные подробности модели, нарушая инкапсуляцию,

D>можно и нужно ли по-другому?
Если от состояния модели зависит то, как ее показывать, значит это не интимные подробности и, соответственно, никакого нарушения инкапсуляции нет.
Хотя можно и по другому. Если в зависимости от счетчика модель может иметь несколько разных состояний, то можно дать не доступ к счетчику, а событие или набор событий срабатывающих при переходе из одного состояния в другое. На эти события подписывается контроллер/презентер и отображает изменения модели, посредством соответствующего view.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[4]: MVC
От: MaximVK Россия  
Дата: 14.09.07 10:12
Оценка:
Здравствуйте, IB, Вы писали:

IB>Если от состояния модели зависит то, как ее показывать, значит это не интимные подробности и, соответственно, никакого нарушения инкапсуляции нет.

IB>Хотя можно и по другому. Если в зависимости от счетчика модель может иметь несколько разных состояний, то можно дать не доступ к счетчику, а событие или набор событий срабатывающих при переходе из одного состояния в другое. На эти события подписывается контроллер/презентер и отображает изменения модели, посредством соответствующего view.

Согласен. От себя добавлю, что в качестве критерия можно использовать ответ на вопрос: Кто ответственен за значение порога 10? Если это некое бизнес-правило модели(например, нельзя добавить более 10 товаров в заказ), то очевидно это личное знание модели и проверка на превышение порога должна происходить в модели. Если это правило относиться к управлению интерфейсом, то в зависимости от ситуации или во вью или в контроллере(в данном случае, в контроллере это будет уместней).
Re[4]: MVC
От: KolanT  
Дата: 14.09.07 10:50
Оценка:

А что будешь делать, если во View7 появиться код вида: if model.getSomeData() > 5 then Show;
Логика выбора view должна быть в одном месте.

А кто сказал что это не правильно? Может по задачи и надо чтобы сработали два view. Иначе...
Я бы тоже поместил логику показа в одно место, но сделал бы это отдельным объектом, что-то типа ViewManager.


А если:

Кто ответственен за значение порога 10? Если это некое бизнес-правило модели...

То тогда имхо в модели должен быть не счетчик, а хотябы элементарный набор состояний.

Короче все зависит от конкретной задачи... Тут можно гадать бесеконечно.
Re[5]: MVC
От: MaximVK Россия  
Дата: 14.09.07 11:45
Оценка:
Здравствуйте, KolanT, Вы писали:

KT>А кто сказал что это не правильно? Может по задачи и надо чтобы сработали два view. Иначе...

Контролировать поведение лучше в одном месте, даже если нам надо, чтобы сработали два вью независимо. Иначе, когда выясниться, что при 20 выскочивших вью система начинает катострофически тормозить и нужно показывать следующую порцию вью только после того, как на этих нажмешь кнопку ОК — придется скакать по всем вью и искать свои проверки.

KT>То тогда имхо в модели должен быть не счетчик, а хотябы элементарный набор состояний.

А как модель узнает, что порог превышен? Чтобы из одного состояния в другое переключиться?

KT>Короче все зависит от конкретной задачи... Тут можно гадать бесеконечно.

Это конечно да, вот только зачем приводить задачи вероятностная мера возникновения которых равна нулю?
Re[2]: MVC
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 14.09.07 13:52
Оценка:
Короче модель это по сути тупое хранилище данных там не должно быть ни какой бизнес логики только извещение подписчикам об изменении ...
но если модель большая содержит много полей много данных возможно вложенных и т.п. и в свою очередь на модели весит куча вьюшек, то тут лучше добавить в оповещение пару параметров (type, object) и тогда слушатели по этим параметрам (или только по типу сообщения) смогут сами решать нужно им сейчас перерисовать данные или это не их данные и они не тормазят работу гуи.

PS. конечно этот вариант для действительно редких случаев ...
Re[6]: MVC
От: KolanT  
Дата: 14.09.07 19:53
Оценка:

Контролировать поведение лучше в одном месте, даже если нам надо

ДА, а если View — отдельные плагины, и сегодня неизвестно какие есть view и как они должны работать вместе.(У меня есть реальный примеры).

А как модель узнает, что порог превышен? Чтобы из одного состояния в другое переключиться?


На то она и модель — это её дело это и есть бизнес логика.
Пример: Перейти в состояние "Попа" если счет меньше 0. — Соотв View покажет сообщение "3".


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

А хде же она должна быть.


то тут лучше добавить в оповещение пару параметров

Надо делать Observer...
Re[3]: MVC
От: KolanT  
Дата: 14.09.07 19:55
Оценка:

Соотв View покажет сообщение "3".


Смотреть повернув голову на лево..
Re[4]: MVC
От: Stormblast http://www.myspace.com/stormblastblack
Дата: 17.09.07 13:18
Оценка:
Здравствуйте, KolanT, Вы писали:

KT>

KT>Соотв View покажет сообщение "3".


KT>Смотреть повернув голову на лево..


это что ?
Re[4]: MVC
От: dolor Китай  
Дата: 19.09.07 13:16
Оценка:
Здравствуйте, IB, Вы писали:

D>>что является вроде как плохим ООП — нарушается принцип tell don't ask, листенер лезет в интимные подробности модели, нарушая инкапсуляцию,

D>>можно и нужно ли по-другому?
IB>Если от состояния модели зависит то, как ее показывать, значит это не интимные подробности и, соответственно, никакого нарушения инкапсуляции нет.
по факту получается что выбор вью зависит от данных внутри модели, логика обработки которых должны происходить там же где и данные, т.е в модели
вот мне непонятно что тут нужно (и нужно ли) нарушить: ООП или MVC

IB>Хотя можно и по другому. Если в зависимости от счетчика модель может иметь несколько разных состояний, то можно дать не доступ к счетчику, а событие или набор событий срабатывающих при переходе из одного состояния в другое. На эти события подписывается контроллер/презентер и отображает изменения модели, посредством соответствующего view.

а почему этой связи (контроллеры оповещаются моделью) ни на одной картинке нету?
ситуация мне кажется тривиальной и должны быть какое-то стандартное решение
Re[5]: MVC
От: dolor Китай  
Дата: 19.09.07 13:29
Оценка:
Здравствуйте, MaximVK, Вы писали:

MVK>Согласен. От себя добавлю, что в качестве критерия можно использовать ответ на вопрос: Кто ответственен за значение порога 10? Если это некое бизнес-правило модели(например, нельзя добавить более 10 товаров в заказ), то очевидно это личное знание модели и проверка на превышение порога должна происходить в модели. Если это правило относиться к управлению интерфейсом, то в зависимости от ситуации или во вью или в контроллере(в данном случае, в контроллере это будет уместней).


порог 10 — это бизнес-правило модели, и я согласн что это ее личное знание,
но как быть несчастному контроллеру, которому нужно выбрать view?

покрасивше конечно выглядит:

if (model.isThresholdExceeded())
   view2.show();
else
   view3.show();

может быть этот вариант мне нужен?
Re[6]: MVC
От: dolor Китай  
Дата: 19.09.07 13:35
Оценка:
Здравствуйте, MaximVK, Вы писали:

KT>>То тогда имхо в модели должен быть не счетчик, а хотябы элементарный набор состояний.

MVK>А как модель узнает, что порог превышен? Чтобы из одного состояния в другое переключиться?

узнать то она узнает, someData — ее свойство, проверка на превышение порога в ее компетенции,
проблема в том, что ей нужно инициировать показ того или иного view, а делать она этого не может
Собственно нужно ей инициировать показ или не нужно (и если не нужно то как тогда)- как раз главный мой вопрос.
Re[5]: MVC
От: IB Австрия http://rsdn.ru
Дата: 19.09.07 14:24
Оценка:
Здравствуйте, dolor, Вы писали:

D>вот мне непонятно что тут нужно (и нужно ли) нарушить: ООП или MVC

Не нужно нарушать ни то ни другое.

D>а почему этой связи (контроллеры оповещаются моделью) ни на одной картинке нету?

На каких картинках искал?

D>ситуация мне кажется тривиальной и должны быть какое-то стандартное решение

Я тебе изложил стандартные решения.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[7]: MVC
От: MaximVK Россия  
Дата: 19.09.07 14:26
Оценка:
Здравствуйте, dolor, Вы писали:

D>Здравствуйте, MaximVK, Вы писали:


KT>>>То тогда имхо в модели должен быть не счетчик, а хотябы элементарный набор состояний.

MVK>>А как модель узнает, что порог превышен? Чтобы из одного состояния в другое переключиться?

D>узнать то она узнает, someData — ее свойство, проверка на превышение порога в ее компетенции,

D>проблема в том, что ей нужно инициировать показ того или иного view, а делать она этого не может
D>Собственно нужно ей инициировать показ или не нужно (и если не нужно то как тогда)- как раз главный мой вопрос.

Вот блин. Это был ответ на:

То тогда имхо в модели должен быть не счетчик, а хотябы элементарный набор состояний.

Поясню еще раз. У модели должен быть и счетчик, и порог, и набор состояний. Если у модели есть только набор состояний, то значит она предоставляет интерфейс для изменения своего состояния и этот интерфейс доступен контроллеру. Это тоже возможно, просто надо решить в чьей ответственности лежит проверка правила превышения счетчика. Это может быть и модель, и контроллер и даже вью. Контроллер, например, может следить за тем, чтобы одновременно на экране было не более 10 окошек. Модели нет дела до этого правила.

Рассмотрим вариант, когда превышение порога — это правило модели. Скажем, количество попыток, которые может пользователь сделать, чтобы ввести пароль. Тогда поля счетчика и порога — скрытые поля модели. Как модель будет сигнализировать о том, что нельзя больше логиниться?
1. Выдавать эксепшен, что количество попыток превышено.
2. Сообщать событием, что количество попыток превышено. Сообщать событием, что состояние юзера поменялось на с Active на Disabled.
3. Предоставлять метод CanUserLogin() или GetUserState().
Ни один из этих вариантов не требует делать поля счетчика и порога публичными и тем более выносить логику проверки правила в контроллер или форму. У контроллера есть вся необходимая информация. В свою очередь, обладая этой информацие контроллер принимает решение, какую view показывать: с полем логина или картинку Access Denied.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.