Pull to refresh

Comments 47

Есть еще одно популярное разночтение. Очень многие под View подразумевают лишь шаблонизатор и вызывают его прямо из контроллера, в то время как есть и иной взгляд — что View лишь представляет полученные от контроллера данные в понятный для шаблонизатора вид, попутно дополняя их данными, не зависящими от текщего пользовательского ввода (например строчку с информацией об авторизованном пользователе).

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

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

Например, классы данных (entity) на сервере будут моделью, классы для получения данных (dao, service) будут видом, а связующая логика (interceptors, security, ioc) будет являться контроллером. Причем в данном случае вид (можно взять другой термин) не будет иметь визуального представления, он будет только предоставлять интерфейс для работы с данными. Тоже самое можно сказать и об интерфейсе пользователя (модель — данные с сервера, вид — интерфейс пользователя, контролер — связующий фреймворк).

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

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

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

p/s
Кстати, большое количество кода бизнес логики на клиенте (клиентский javascript толкает к этому) ведет к еще одной проблеме: надо валидировать не только данные на клиенте и сервере, но и правила вызова методов (функций) на клиенте и сервере. Но такова судьба…
Я думаю, что большинство программистов, независимо от их собственного мнения, ориентируются на систему MVC, предложенную тем фреймворком, на котором они пишут.

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

Это если не учитывать программирование for fun с нуля.
Чем ваша точка зрения отличается от ещё одной из тех, что вы перечислили в начале? MVC — это идея, а как её реализовать, решает каждый сам, исходя из поставленной задачи и условий, в которых находится. И это не серебряная пуля, городить везде MVC — не самый удачный вариант. Как и городить везде JavaScript.

Лично я всегда придерживаюсь двух правил: частное лучше общего и меньше — больше. Очень, знаете ли, помогает.

P.S. Sencha (бывший ExtJS) вполне нормально используется в админках, и выглядит чаще всего именно как один скрипт, подключенный к пустой HTML страничке. Ничего радикального, очень удобный фреймворк.
Отличается: я подчеркиваю, что разделение модели, контроллера и представления не идентично разделению данных, логики и интерфейса. В результате предлагаю MVC разделять, а все, что касается предметной области (данные, логику и интерфейс) наоборот объединять. Еще — стараюсь показать, что есть много взглядов на одну задачу и не нужно думать, что произнося MVC Вас сразу все поймут однозначно, как, наприер, если Вы произносите «наследование» или «фабрика». Ну и последнее — провожу парралели с ISO/OSI, показывая, что в трехзвенке (если речь идет о веб-приложении, а не просто сайте) модель должна быть развернута частично во всех трех слоях, чтобы были адекватные горизонтальные связи.
Вы не поняли меня :) Я имел ввиду, что ваша точка зрения — одна из многих, вот и всё.
Тогда согласен, я об этом же, в последнем абзаце: «Я не претендую ни на авторство… ни на то, что это единственный и самый правильный подход».
О, такой еще не читал, спасибо, ознакомлюсь. Особливо нравится картина Кандинского на обложке, очень в тему.
Наступая на грабли выявил такую закономерность (поправьте если что). В идеале:

Model — Все объекты и вся бизнес логика. Включая «простые» методы (например getProductName(), purchaseProduct(), т.е. всё что НЕ зависит от пользователя, делает требуемое действие без проверок на есть ли право и т.д.) так и «сложных», типа purchaseProductWithUserDiscountAndSendMail(). Никаких конфигов внутри, все передается параметрами. Всё для того чтобы был прозрачен интерфейс и легко тестирование.

View — только логика вывода (foreach, if...else, порой и сложная логика) тех данных что переданы в него. Результатом может быть HTML, или XML, или PDF, только что-то одно. Выбрасывается с новым дизайном, как шкура змеи.

Controller — нечто что знает всё об окружении (платформа, пользователь, устройство ввода) и передает данные от пользователя к модели и генерирует данные для View. Также инициирует нужные объекты модели, формы. Очень зависит от конфига (в основном передает значения в аргументах модели). Нельзя сказать что в контроллере нет бизнес логики, хотя логика здесь «управленческая».

В итоге модель это готовое API, всё тестируется. Контроллер — платформенный мусор, View — верстальщицкий мусор. Дальнейшее разделение (View на Renderer+Templater) по желанию и потребностям.
Вообще все совпало со статьей, ИМХО. Меня всегда коробило от того, что в одних и тех же классах программисты смешивают предметную область и, как Вы правильно заметили, «платформенный мусор». Класс должен относиться или к реальному миру или к технологиям, именно это нужно разделять.
Я думал о том же с момента моего ухода с delphi и природа только недавно подарила мне решение которое помогло мне. Это GWT и GWT MVP фреймворки. Как следствие:

> при полном отказе от HTML и сведении страницы к одному тегу подключения JavaScript

Именно так, клиентское приложение по сути вызов одного JavaScript'а.
Учитывая что я разрабатываю именно Web приложения и у меня нет необходимости в том, чтобы мое конечное приложение корректно индексировалось поисковиками. Таким образом клиентский код и код среднего звена у меня разделены. Это неплохо разгружает среднее звено и позволяет обслуживать больше клиентов.
> Storage-Model-Application-Renderer-Template-Model
Я считаю, что в вашем случае GWT MVP позволит избавиться от уровней: Storage, Application, Renderer и Template. И двух моделей — так как GWT позволяет иметь один и тот же Model как на клиента так и на сервере, для передачи используется GWT RPC.

MVP фреймворк отличается тем, что пользователь взаимодействует с конечным View который выстреливает евенты которые обрабатывает Presenter который оперирует с Model и если есть необходимость c View.
Вообще различие между MVP и MVC хорошо проиллюстрировавший на рисунке:
image
Как видно MVP более последователен, как следствие меньше разночтений.
Интересная картинка. Из того что понял я ( а я изучаю этот вопрос недавно) основная задача MVC максимально выделить шаблоны отображения, чтобы озадачить работой много дизайнеров и иметь выбор тем. Если брать какие нибудь типовые сайты, или софт типа интернет магазинов, то мы обычно имеем один блок логики приложения, и сотни вариантов визуализации.

MVP довольно сильно усложняет вышеописанную задачу, поскольку View становится полноценным блоком кода. Этот подход приемлем для озадачивания работой кучи программистов в каком нибудь бизнес-ориентированном проекте где наоборот дизайн остается постоянным, а бизнес-логика гибко расширяется и изменяется.
Вообще, я поднял этот вопрос чтобы показать, что есть разные точки зрения и MVC — это не монолит, а просто направление, в котором все двигаются по-разному. Ну и конечно, выбор или создание архитектуры диктуется задачей, нет решений на все случаи жизни, как бы не хотелось их заполучить.
На самом деле никто и ничего не усложняет выбор того или иного патерна вопрос скорее религиозный.
И часто сделать выбор программисту помогает фреймворк. если вы используете java то там MVP проповедуют: Swing, JFaces, GWT и Vaadin.
Так как я использую GWT, Google сделал выбор за меня. И естественно google лоббирует выбранный им Pattern.
Привожу ссылку на презентацию, поискав по ключевому слову
«Decoupling via MVP» можно найти часть презентации посвященной именно паттернам.

Их основной предпосылкой для выбора MVP я считаю вероятность того, что приложению может понадобится несколько конечных реализаций интерфейса к примеру Web и Desktop.
В случае если клиент взаимодействует непосредственно с контроллером где гарантия того, что конечно представление сможет гарантировать возможность такого взаимодействия?? Как следствие это может повлечь необходимость создание контроллера под каждую реализацию каждого конкретного View. При полноценном View можно гарантированно разделить бизнес логику и отображение.
И тут может гибко меняться как логика без изменения отображения так и отображение меняться не задевая логику приложения.

Так что я считаю MVP ничего не усложняет при условии 1 View и 1 Контроллера кол-во строк кода будет неизменным. А вот при увеличении кол-ва View считаю MVP более удачной моделью.

За последние две недели, в беседах с десятком знакомых программистов я выяснил, что все представляют себе MVC совершенно по-разному. Доходит до диаметрально противоположных взглядов,
Я общаюсь с разными программистами уже больше 10 лет и каждый из них видит MVC по своему, и Вы правы — даже противоположные взгляды. Надо понимать, что MVC — это парадигма, а не догма. И по этому каждый из них по своему прав.

Существует первый взгляд на MVC В WEB есть свои адаптации, и их несколько видов…

В целос статья мне понравилась,
спасибо, многим будет полезно.
Все источники утверждают, что MVC пришел из smalltalk. Думаю первый взгляд надо искать там. :)
Сейчас мы с товарищем доделываем один проект, начатый с нуля. Так вот, в начале мы приняли решение взять за основу MVC с целью разделить представление, данные и логику. Т.к. опыта мало, мы натыкались на различные грабли, было желание всё глобально переписать/перепроектировать, создать еще с десяток классов для чего-нибудь…

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

Это я к тому, что понимание MVC у всех не только разное, но и некое «универсальное понимание» особо не нужно.
В статье упоминается модель MVVM, но мне кажется, что это не совсем точное описание и применение данной модели. Более того, я считаю одна из проблем использования MVC кроется как раз в отсутствии MVVM.
MVVM — Model — View — ViewModel — это патерн, такой же как патерн MVC и совместное использование этих патернов в большинстве случаев дает хорошие результаты. Если кратко, то MVVM служит для решение следующий проблемы. У вас есть бизнес модель, построенная по результатам анализа, и она нормализована и адекватна, т.е. не должна содержать дублирования данных и полностью отражать бизнес сущности. Однако, если вы берете эту модель как есть, и пытаетесь вставить ее в представление вы получаете интерфейс, который не соответствует логике пользователя и юзабилити. В итоге мы имеем интерфейс к базе данных — в лучших традициях Дельфи и Фокспро. И это не очень хорошо с точки зрения пользователя.

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

Ну и конечно, что MVC, что MVVM, Repository, UnitOfWork etc. это всего лишь патерны, и использовать их нужно осмысленно, понимая, для чего ты это делаешь, исходя из задачи.
Я предлагаю посмотреть на SpringMVC. Там в reference есть примеры, и в моем понимании MVC там реализован хорошо, а именно:
— Model — это чисто POJO (как Command bean, так и просто DTO для view)
— Controller — то что, заполняет модель или считывает с нее данные и делает с ними, что требуется (а именно передает на сервисный уровень, где происходит нужна бизнес логика)
— View — то что показывает модель

Ничего лишнего, и четкое разделение по зонам ответственности.
Вот именно POJO и невозможно пользоваться — хороших 75% аппов — это тупой «pass-through» в бакенд. Нафиг вообще objects? Именно поэтому все вцепились в скаффолдинг
Самое основное заблуждение, что люди считают MVC чем-то законченным, а не парадигмой, это всего лишь советы, а не требования. И соответственно взгляды могут отличаться.
Рассматривайте вид как шаблонизатор. В нём не объявляется новых переменных и он может работать только с уже переданными данными.
Модель хранит всю информацию о данных. Включая, например, правила валидации и SQL.
Но вся логика и операции происходят в контроллерах. Например, сама валидация данных в соответствии с моделью.
Контроллер будет ядром системы и не будет захламлён, например, SQL-запросами.

Что лично я встречал чаще всего — это то, что программисты внезапно переходят от MVC к привычному им подходу. Без предупреждения, просто начинают клепать какие-то уберклассы, которые объявлены как модели, но вместе с тем работают как контроллеры и ещё умудряются управлять представлением данных. Вот это — реально проблема. А различные трактовки MVC всегда можно согласовать.
UFO just landed and posted this here
UFO just landed and posted this here
А у меня как-то наоборот — при рефакторинге «плоского» PHP-спагетти MVC вырисовывается сама, без целенаправленных усилий с моей стороны, фактически только следуя принципам типа DRY и SOLID.
Статья хорошая, но попытка придумать свой mvc — бессмысленная. из паттерна нужно вынести только главную идею — разделяй и властвуй, плевать как называются слои, главное чтобы они были максимально независимыми и легко заменяемыми.
и еще чтоб летало на нагрузках…
реальные нагрузки встречаются очень-очень редко редко. а оптимизация под нагрузки как раз легко должна решаться заменой сдлоя на более оптимизированный (в начале проекта стоит отдавать предпочтение скорости разработки и поддержки).
собственно для этого весь этот слоёный пирог и нужен, а то линейный код иногда писать в разы проще и быстрее по началу.
>реальные нагрузки встречаются очень-очень редко редко
мой предшественник так наколбасил с иерархией категорий,
что в реальных условиях сервер умирает на таймауте…
Дык, MVC — это только паттерн, а не архитектура. Архитектура каждого отдельного MVC-фреймворка может отличаться очень сильно, но при этом быть MVC (или его разновидностью, HMVC, MVP, MVVM и прочие «MV»).

Сегодня MVC стал популярен в основном благодаря применению для веба — и большинство из появившихся фреймворков — реализация MVC в виде архитектурного паттерна Front Controller. Очевидно, что это только один из вариантов использования MVC, более того, в очень конкретном контексте (веб, принимая во внимание HTTP и его особенности и прочее).
Да, но MVC это скорее архитектурный паттерн, чем паттерн ООП или программирования вообще. MVC можно реализовать вообще даже на bash или на си. А при реализации Front Controller (единая точка входа) в веб-сайтах и веб-приложениях, MVC сам напрашивается. Посмотрим, какие решения принесут нам следующие 2-3 года, ведь скоро во всех браузерах (включая мобильные девайсы) будут доступны хорошие веб-сокеты с постоянным TCP коннектом и можно будет писать полноценные клиент-серверные протоколы, без AJAX/JSON и Comet (Long-Pooling). Думаю, это несколько изменит архитектурный мейнстрим в вебе.
Верно, MVC — архитектурный паттерн, но очень-очень общий. Он ничего не говорит о конкретном окружении и контексте. А Front Controller — это очень конкретный частный случай. Ну, собственно, я вижу, мы говорим об одном и том же. Я просто написал это к теме топика — ибо многие путают именно «MVC как таковой» с Front Controller-ом.
Насчет ближайших перспектив — не уверен, что что-то очень уж сильно поменяется. Ведь и сейчас в целой куче проектов бывает удобнее даже для толстых клиентов обращаться к сервисам через HTTP. Для сокетов, безусловно будут свои задачи, но вряд ли с их повсеместным появлениям куда-то уйдет старый добрый stateless-http.

Впрочем, конечно, я бы не загадывал однозначно, ибо неизвестно. Известно одно — веб будет развиваться дальше и очень стремительно.
В HTML5 мы получаем SQL-совместимую СУБД, и полноценные сокеты, а на сервере, все к тому идет, что мы получим stale-full серверное приложение на node.js или же просто сохраняющее состояние в memcached или в др. месте. Конечно же, это нужно только для приложений, а stateless остается для сайтов и веб-страниц, там состояние не нужно совершенно. Прикладным же приложениям без машины состояний ни как нельзя, состояние нужно и в UI и в сервере приложений, ну а в БД оно есть само собой.
Что дает хранение состояния и сокеты (просто мысли в слух, это все очевидно):
— Приложение может жить без постоянных запросов к серверу достаточно продолжительное время, исполнять свою логику, сохранять в локальную базу и не бояться потери данных;
— Возможность не перегружать страницу;
— Минимизация трафика;
— Возможность синхронизировать экраны у пользователей;
— Возможность управлять экраном браузера с сервера (не заменимо в приложениях групповой работы и играх);
— Возможность работы в оффлайне;
— Возможность транслировать события в две стороны между моделью, развернутой в браузере и в памяти на сервере.
Ну это только одни из кучи сценариев.

«Приложение может жить без постоянных запросов к серверу достаточно продолжительное время, исполнять свою логику, сохранять в локальную базу и не бояться потери данных»
Зависит от того, какие данные — если настройки, данные текущей сессии — да, но если данные, меняющие общее состояние системы — это целая задача все правильно синхронизировать. Вообще, «проблема Stale-Data» — большая и обширная тема :)

«Возможность управлять экраном браузера с сервера (не заменимо в приложениях групповой работы и играх)»
Это бы круто, да.
У меня сейчас как раз заканчивается разработка одного приложения, где пользовательским экраном управляет сервер напрямую, то есть, поток команд льется через Comet (Long-pooling) и каждая команда интерпретируется и исполняется джаваскриптом на клиенте. Это как в X-Window System в *nix системах. Красота, в общем. Но я бы с большим удовольствием использовал сокеты, чем Long-pooling. Кстати, как раз в этой задаче стоит вопрос о локальном хранении состояния, т.к. браузеры могут отваливаться и быть в оффлайне (работают по wi-fi и мобильному инету). Тогда конечно поток команд с сервера прекращается, но события происходят, и при восстановлении соединения, нужно все это отдавать серверу. При этом, пользователю будет очень обидно, если события потеряются, а такое сейчас случается, если при пропадании связи он жмет рефреш.
Интересная тема.

Пара вопросов:
— А что за приложение, если не секрет?
— Чем обусловлено такое явное предпочтение сокетов, нежели Comet?
Проект: телевизионная тема, идея — синхронизировать браузер с телеэкраном, более подробно не могу открыть, к сожалению. Ну сделано то на комете конечно сейчас, но будет постепенно переезжать на сокеты. По многим причинам: комет вводит браузер в состояние загрузки страницы, это много на что влияет, например, во многих браузерах крутится бублик, а чтобы не крутился, нужно делать комет в айфрейме — это уже заплаты. Еще: комет держит на сервере процесс специально под соединение, а у меня десятки тысяч пользователей. Если делать на сокетах, то такого не будет, сервер можно будет сделать на C#, Java, Node.js или др. и это будет один процесс серверный и в нем просто много сокетов открыто, а логика в памяти на них на все один раз развернута (автор тяжко вздыхает, вспоминая о Delphi). Ну и сокеты — это двухсторонний обмен, т.е. и клиент может присылать пакеты и сервер, можно синхронно, а можно и асинхронно, как в моем случае и нужно.
Как-то мне кажется, что очень многие веб-приложения рассчитаны либо взаимодействие пользователей в реал-тайме, либо на возможность пользователю получить доступ к своим данным с разных девайсов. Тут локальное хранилище и сокеты обеспечит по сути только инкрементальную синхронизацию локальных и серверных данных в том числе по инициативе сервера.
Вопрос вот в чем — в какой срок ваш подход позволит поднять систему с «нуля»?
Я не знаю ни одного комплексного подхода реализованного на уровне «outofthebox».
Тот, кто восхваляет Hibernate или смакует MVC с LINQtoSql, должны себя спросить — могут ли они сделать «бизнесс форму» с форен ключами и.т.д. за 20 минут. Delphi, кстати, почти был основан на view model (tfield, tfielddef) и, как результат, многие задачи решались проще чем в современных «чистых» frameworks.
Ну прогресса в современных средствах разработки не видно ни для разработчика, ни для конечного пользователя. Мощности растут, а вот программисту создать или пользователю заполнить простую форму, к примеру, в современных технологиях дольше сейчас, чем это было в консольных программах, когда еще все псевдографикой рисовали и мышку не использовали. Сейчас разработчик, к сожалению, погружен в концептуальные подходы, паттерны и изобретательство, вместо того, чтобы думать только о предметной области, о поставленных задачах. Это говорит о том, что технологии сырые и зеленые еще, «outofthebox» для прикладных приложений нету, а даже если кто-то себя так и позиционирует, то это системы узко специализированные (типа CMS, CRM, SCM, BPM, документооборот и бухгалтерия), а вот именно прикладных платформ нет и не предвидится. Корпорации заняты войнами технологий, а их можно выиграть только внедряя что-то массовое и не оставляя конкурентам надежды на интеграцию и стабильность. Вот и видим только ПО массового потребления, коммуникационное, офисное, системное, работающее с информацией на уровне файлов и не углубляющееся в прикладные базы данных. Развитие прикладного ПО, как мне кажется, вообще пришлось на 1999-2003 годы, после этого оно стало вялотекущим из-за проблем с инструментарием и из-за заложенных во имеющиеся платформы ограничений. Сейчас вот веб-приложения начали понемногу приближаться к формированию устойчивой среды из стандартов, подходов и средств, но она все еще очень разношерстна, и только в 2010 году наконец браузеры дали нам инструментарий который был доступен для оконных приложений (в том же Delphi) еще 10 лет назад.
Sign up to leave a comment.

Articles