Опять про MVC

Oddinn

Новичок
Опять про MVC

У меня тут возник один вопрос теоритический по поводу паттерна MVC. На phppatterns.com в примере к MVC предлагается создавать несколько классов-контроллеров под разные случаи жизни и потом в index.php создавать нужный. То же самое и для View. А вот правильно ли с точки зрения MVC будет создать один класс-контроллер и в нем обрабатывать запрос и создавать соответствующую модель и представление?

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

И заодно такой вопрос: насколько правильно с точки зрения шаблона MVC создавать объект View, в октором прописывать логику отображения? Может лучше прямо в контроллере определить логику выбора шаблона и его подключение?
Заранее спасибо за ответы.
 

_RVK_

Новичок
Oddinn
ИМХО, вопрос из области "как удобнее". Лично у меня реализован 1 главный контроллер, и есть возможность часть логики вынести в отдельные контроллеры. поищи по слову SuperAction, это уже здесь обсуждалось.
Насчет View. В моей реализации по умолчанию контроллер выберает шаблон для отображения, но у модели может быть и собственный шаблон.
 

Oddinn

Новичок
_RVK_
Спасибо. Действительно, наткнулся на очень полезное обсуждение. Пойду укладывать все это в голове.
 

Alexandre

PHPПенсионер
если копнуть глубже, в паттернах есть два способа реализации:
- как контроллер страниц, т.е куча контроллеров на свой экшен
- как контроллер запросов, т.е. один контроллер на кучу экшенов и страниц
 

pachanga

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

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

Alexandre

PHPПенсионер
Вопрос имплементации MVC очень расплывчатый
как говорил мой бывший ведущий программер:
нет четкой границы между слоями, по этому реализовывать MVC надо так, как сам обозначишь эти границы.
 

Oddinn

Новичок
Автор оригинала: Alexandre
как говорил мой бывший ведущий программер:
нет четкой границы между слоями, по этому реализовывать MVC надо так, как сам обозначишь эти границы.
Да, я так и делаю в результате. Подход, предложенный _RVK_ очень помог.
 

whoarym

Guest
imho: одному view соответсвует один controller. фсе.
index.php просто работает как диспетчер.

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

pachanga

Новичок
одному view соответсвует один controller
И хотя я ранее говорил про расплывчатость, позвольте не согласиться, т.к это слишком жесткое ограничение. Почему вообще view должен быть привязан к controller? Скорее наоборот, это controller решает, какой именно view ему использовать в определенный момент.
 

ForJest

- свежая кровь
Вообще на phppatterns по-моему не слишком удачный пример MVC.
Как я вижу собственно говоря разделение ролей.
Controller - управляет созданием объектов, связями между ними.
Model - хранит в себе все данные, которые нужны View. Предоставляет все необходимые методы для получения данных, в которых нуждается View. Никак не изменяет данные.
View - занимается исключительно отображением данных, которые берёт исключительно из Model. Если контроллеру нужно передать что-то в View он передаёт эти данные модели, а та уже передаёт их View.
-----------------------------------
При такой схеме мы имеет простой дизайн кода, который очень легко контроллировать и изменять. Преимущества:
1. Всегда известно куда складывать данные
2. Всегда известно откуда будут браться отображаемые данные
3. Один и тот же View может иметь в качестве источника данных несколько моделей. Модели создаются Controller'ом
4. Одна и та же модель может иметь несколько представлений - достаточно создать нужный View и передать ему нужную модель.

-~{}~ 21.08.05 03:14:

вот правильно ли с точки зрения MVC будет создать один класс-контроллер и в нем обрабатывать запрос и создавать соответствующую модель и представление?
Да - правильно.
Model и View связаны неразрывно. Model не может предоставлять меньше функций доступа к данным, чем требует View.
Т.е. допустим мы можем иметь модель
PHP:
class Model
{
function get_data_one()
{
...
}
function get_data_two()
{
...
}//class ends here
}
и два View
PHP:
class View1 extends BaseView
{
function get_template_name()
{
     return 'tpl1.tpl'
}
function display()
{
    $this-> assign('data1', $this-> Model-> get_data_one());
}
}//class ends here

class View2 extends BaseView
{
function get_template_name()
{
     return 'tpl2.tpl'
}

function display()
{
    $this-> assign('data2', $this-> Model-> get_data_two());
}
}//class ends here
И таким образом одна модель, предоставляющая широкий интерфейс для получения данных имеет два представления, которые используют не все данные.
Или же можно создать две отдельных модели - каждая из которых будет нужна только одному view - всё зависит от конкретного дизайна кода.
Ну и реально, как мне кажется лучшим дизайном MVC является тот где
1. View запрашивает данные у модели
2. Данными "кормят" модель и только модель, даже если кажется что наиболее "прямой" путь - это задать эти данные в View. Если пойти этим "прямым" путём в угоду размышлениям о производительности - это потом даст себя знать.
3. Контроллер таким образом знает решает лишь
- какой view и модель ему создавать.
- какими данными кормить модель
4. После того как модель создана, накормлена данными, создан view контроллер просто связывает - задаёт View источник данных, объект откуда брать данные. Которым является модель.

Я беру для рассмотрения некий "конечный" контроллер. Потому что все остальные вещи, которые произоводят диспетчирезацию событий контроллерами не являются - не нужно их даже называть контроллерами :). Даже совершение каких либо действий не подходит под модель MVC, с моей точки зрения.
Model-View-Controller это связка предназначенная исключительно для отображения данных/состояния системы. Обработка должна происходить до.
Можете назвать это Actioner - пусть он хранит в себе и controller и некие actions. Но MVC лишь отображает данные. Этот паттерн имеет, с моей точки зрения узкую область применения. А повсеместная его распространённость и притягивание его за уши на все случаи жизни лишь указывает на то, что среднестатистический программер знает лишь эти три волшебные буквы :)
--------------------------------------------------
MVC мне представляется следующим образом (грубо и аналогия далеко не полна)
- Модель - это система датчиков автомобиля
- View - это устройства визуализирущие данные о состоянии автомобиля.
- Controller - сборочный конвейер, который для нужных марок автомобиля ставит нужные наборы датчиков и для разных обивок салона ставит приборные панели разного цвета.

-~{}~ 21.08.05 03:37:

---------------------
Ну ещё одно ОЧЕНЬ ВАЖНОЕ ЗАМЕЧАНИЕ.
Для тех кому лень это всё читать или кто не понял ещё эту простую мысль.
MVC - это
1. Model
2. View
3. Controller.
Три вещи. Ещё раз повторяю - это ТРИ вещи. Если в вашем дизайне кода появляется этих вещей больше - например добавляются некие Actions - то это уже не MVC.
Потому что паттерн MVC имеет смысл лишь в пределах взаимодейтвия ТРЁХ ролей. Всего трёх.
И Controller должен знать лишь о двух других ролях и управлять лишь двумя объектами/ролями - Model и View. И ничем больше.
Проверьте свой дизайн кода - если контроллер занимается больше чем созданием View, Model и наполнением данных модели - это не MVC.
Если View занимается получением данных из внешних источников - это не MVC.
Если модель вызывает методы View - это не MVC.
Если контроллер создаёт другие контроллеры и не имеет модели или View - это не контроллер и это не MVC.
 

pachanga

Новичок
Три вещи. Ещё раз повторяю - это ТРИ вещи. Если в вашем дизайне кода появляется этих вещей больше - например добавляются некие Actions - то это уже не MVC.
Потому что паттерн MVC имеет смысл лишь в пределах взаимодейтвия ТРЁХ ролей. Всего трёх.
А вот я себе опять позволю не согласиться с вышесказанным :) По-моему, неправильно рассуждать о MVC в столь детальном плане:

Controller - управляет созданием объектов, связями между ними.
Model - хранит в себе все данные, которые нужны View. Предоставляет все необходимые методы для получения данных, в которых нуждается View. Никак не изменяет данные.
View - занимается исключительно отображением данных, которые берёт исключительно из Model.
Это слишком буквальное понимание данного паттерна:

class Model
{
function get_data_one(){}
}
MVC, как я уже говорил выше, это архитектурное разделение на слои различной программной логики(т.е это не просто класс Model, View и Controller). Имплементация совершенно не имеет значения, главное то, что у вас есть концептуальное разделение ролей составных частей MVC.

Для меня Model - это совокупность бизнес/доменной логики + средства организации доступа к данным. Т.е это не банальные контейнеры для данных(хотя в простейшем случае так оно может и получиться), это целая доменная модель со своими различными отношениями между объектами, правилами валидации и проч. Я нахожу Model одним из самых важных слоев MVC, т.к именно там происходит все "самое интересное".

View - просто средства визуального представления Model: шаблонизаторы, XML + XSL и проч. Кстати, не считаю зазорным, если View имеет средства для прямого обращения к данным Model и не считаю это нарушением MVC.

Controller - это различные средства координации Model и View. Я считаю что и Action также относится к Controller, если об этом думать в более глобальном смысле.

Следует также понимать, что при этом могут существовать отдельно от MVC и другие слои, которые однако могут вместе переплетаться. Скажем, чисто утилитарный слой, который в себе инкапсулирует вызовы к системным функциям(файловая система, дата, время и проч.). Нельзя же сказать, что является нарушением MVC то, что из Controller или View происходят обращения к системным вызовам файловой системы.

Поэтому сказать "вот это MVC, а это нет" нельзя, не найдя в системе класс Model или View. Требуется намного более тщательный анализ.

P.S....к такому пониманию MVC я пришел далеко не сразу, лет так 5 назад, когда мы кодили кошмарный LIMB 1.x. У нас именно так и было, только еще "интереснее" :) Были классы Model, View и Controller для каждого компонента(мы мыслили компонентами Delphi), что было космической нелепостью.
 

ForJest

- свежая кровь
Ну MVC это всё таки шаблон проектирования :). И всё же он раздаёт роли объектам, а не целым подсистемам :).
Просто у тебя так получается MVC это шаблон, который задаёт контекст для всех остальных что ли?
Опять же если нельзя чётко назначить роль объекту - то может быть просто ты используешь термины не для того, для чего они предназначены?
Этим, как я вижу и грешат наши веб девелоперы - сейчас MVC куда не плюнь везде говорят. Из обычного шаблона проектирования сделали целую религию.
Ну блин. Всё равно что назвать Фасадом все функции системы.
Или адаптером назвать реализацию проектf. Ведь проект это по сути дела адаптер функций PHP к требующимся нуждам?
Или не так?
MVC это узкое понятие. Это шаблон проектирования. Не надо из него делать религию.

-~{}~ 21.08.05 11:36:

http://patternshare.org/default.aspx/Home.PP.ModelViewController
Хотя видимо я тоже неправ :)

Ба. Что я нарыл таки
http://patternshare.org/default.aspx/Home.PP.PageController
Т.е. то что я описывал это по сути реализация Page Controller один в один :).
Читаем дальше
http://patternshare.org/default.aspx/Home.PP.FrontController
Это контроллер, но там уже, заметь нет ни модели ни View.
Народ читайте и обретайте новые термины :)
 

pachanga

Новичок
Автор оригинала: ForJest
Ну MVC это всё таки шаблон проектирования :). И всё же он раздаёт роли объектам, а не целым подсистемам :).
Как знать, как знать :) Как раз на то они и паттерны, т.к жестко не определяют имплементацию.

Просто у тебя так получается MVC это шаблон, который задаёт контекст для всех остальных что ли?
Ээээ...наверное правильно было бы сказать, что можно понимать MVC как в "макро", так и в "микро" смысле, что ли... Конечно, когда мы рассуждаем о GUI desktop приложения, там можно довольно четко выделить MVC для графических элементов(собственно, именно при разработке таких приложений, разработчики Smalltalk стали впервые упоминать MVC). Вот виджет, вот у него есть контроллер, некоторая модель и представление. Т.е здесь MVC применимо в микро смысле. Однако ничто нам не мешает применять MVC для целых архитектурных слоев, т.е. в макро смысле. Надеюсь, я не очень загнул...

Опять же если нельзя чётко назначить роль объекту - то может быть просто ты используешь термины не для того, для чего они предназначены?
Ну вот смотри, не будем же мы разрабатывать огромные и неуклюжие god-like классы Model, View, Controller, только для того, чтобы буквально следовать MVC.
Вокруг каждого составляющего триады MVC в приложении разрастается целая инфраструктура со своими внутренними связями и хитросплетениями.
 

ForJest

- свежая кровь
pachanga
Ну вот глянь по ссылкам, почитай.
MVC получается это вообще не шаблон проектирования, пожалуй. Это парадигма. Или идея или направление что ли.
Вот PageController - это реализация MVC - конкретная. И единственная найденная на сайте.
FrontController это уже другой шаблон, который рассматривает взаимодействие другой, не MVC парадигмы с одной из частей MVC - контроллером. Но назвать
FrontController + 3 PageController ёмким словом MVC - нельзя.
Потому что да - есть разделение, благодаря которому появились сущности Controller в паттерне PageController.
Но с точки зрения FrontController (который по сути является, по-моему реализацие паттерна Proxy) нет никакого MVC - т.е. ему пофигу на модели и представления.
Вот об этом я и толкую - в слово MVC впихнули всё-на-свете и теперь бьются об эту аббривеатуру.
 

pachanga

Новичок
Автор оригинала: ForJest
MVC получается это вообще не шаблон проектирования, пожалуй. Это парадигма. Или идея или направление что ли.
Скорее всего да, наверное, правильно думать об MVC именно в таком ключе.

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

ForJest

- свежая кровь
Ну теперь мне понятно в принципе откуда растут ноги у повсеместного MVC-ирования :).
Сколько ты знаешь конктреных паттернов, которые можно назвать MVC? В узком смысле :). Там где Model View Controller именно? :)
----------------------
В общем брожение понятно. Его запихали в шаблоны проектирования, а на самом деле это парадигма разработки :). Отсюда полная сумятица. И плавает это MVC как... Ну короче нету ему домика :).
 

Oddinn

Новичок
То, что MVC не является шаблоном проектирования - написано много где (насколько я помню, даже у GoF). Да и мой скромный опыт говорит, что MVC - это подход к проектированию приложений, а не шаблон. MVC включает в себя несколько шаблонов, причем в разных реализациях эти шаблоны могут отличаться (как правильно сказал ForJest - это парадигма). Сейчас вот специально открыл книгу Э. Гамма, там прямо так и написано: "Знакомство с паттернами проектирования, встречающимися в схеме MVC...". pachanga абсолютно правильно сказал, что MVC лишь предлагает схему разделения на слои программной логики, но не паттерн проектирования. И мой вопрос заключался именно в том, как это архитектурное решение наилучшим образом можно применить при рзработке именно WEB-приложений.
 

Alexandre

PHPПенсионер
Это парадигма. Или идея или направление что ли.
Ноги этой идеи растут от JSP, когда:
сама JSP страница играла роль представления
- связанный с ней сервлет - контроллером, а
- а компонент EJB (зерно кофе ) - за данные (Модель и логика).

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

Что вообще мешает эту парадигму перенести на PHP:

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

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

Концепция MVC, хорошо уживается с концепцией Рефакторинга.
 

ForJest

- свежая кровь
Oddinn
То что ты спрашиваешь хорошо рассказано в двух простых ссылках
http://patternshare.org/default.aspx/Home.PP.PageController
http://patternshare.org/default.aspx/Home.PP.FrontController
Нет. В трёх простых ссылках
http://phpclub.ru/talk/showthread.php?postid=508466#post508466 ещё ;-)

-~{}~ 22.08.05 11:24:

Alexandre
- класс модели формирует необходимые данные в соответствие с логикой, делает апдейт БД (модели) ,
готовит данные для представления
Это ошибка. Апдейт данных делает контроллер. Посмотри на PageController на схему - там всё написано.
Модель _предоставляет данные_. А не занимается их обработкой. Обработкой занимается типа контроллер. Он занимается всеми изменениями - это его роль - решать и изменять.
Остальные две роли пассивные.
Модель - имеет входы для настройки себя перед выводом
View - спрашивает модель данные, в которых он нуждается.
 

Ямерт

The Old One
ForJest
Если в вашем дизайне кода появляется этих вещей больше - например добавляются некие Actions - то это уже не MVC.
Action - это термин из одного из популярнейшших MVC-фрэймворков для Java - Jakarta Struts. В PHP это переложено с Java, например, в проекте phpMvc. По сути Action - это и есть контроллер. ActionForm, бобы - модель. View - это либо JSP, либо Velocity,
либо ещё что-то. Короче говоря, просто термины другие, а суть та же.
З.Ы. Кстати, говоря о "SuperAction". В Struts есть такая вещь как класс RequestProcessor, который обрабатывает ВСЕ запросы - потом выбирает нужный Action, и передаёт ему управление. Очень удобно. Грубо говоря, в PHP аналогом RequestProcessor может являться единый index.php, через который будут идти все запросы.
 
Сверху