Что отвечает за работу с данными в паттерне mvc
Паттерн MVC на клиенте
MVC – паттерн разделения приложения на 3 основных компонента: модель (Model), представление (View), контроллер (Controller).
MVC паттерн был впервые описан Трюгве Реенскаугом в 1978 году. Который изначально использовался для построения графических приложений. Со временем этот паттерн перешел и в веб-приложения. Сначала MVC пришел на серверную сторону с такими фреймворками Ruby and Rails и ASP.NET MVC Framework. В конце концов стал применяться и на клиентской части, для управления сложностью и широтой функциональности. На данный момент имеется иерархия моделей на базе MVC: MVC, MVP, MVVM.
Основной концепцией MVC являетя разделение обязанностей, то есть модель данных не имеет зависимости от бизнес-логики и логики представления. На клиенте же происходит разделение данных (модель), от логики (контроллер), которая работает с этими данными, и HTML кода (представление), то есть представления.
Стоит заметить, что паттерн имеет некоторые различия в применении в клиентском и серверном приложениях.
Как это выглядит для сервера:
Отличным примером использования шаблона MVC являются SPA приложения. Далее рассмотрим признаки MVC в типичном SPA приложении.
Этот вариант реализации MVC подходит для SPA приложений, также существует вариант, с одним отличием, что клиент получает и отображает данные минуя котроллер.
Опишем подробнее каждый из элементов паттерна.
Модель (Model)
Модель содержит в себе данные, с которыми работает пользователь. Существует два типа моделей:
Контроллер (Controller)
Контроллер является связующей частью между моделью и представлением. Он содержит логику необходимую для представления модели и операций над ней.
Контроллер должен содержать логику:
Контроллер не должен:
Представление (View)
View на клиенте отвечает за отображение данных в браузере. Представление содержит в себе разметку и логику для отображения. Тем не менее оно не должно содержать сложную логику, которая должна быть в контроллерах, и логику манипляций с данными, которая относится к модели. Содержание логики в шаблонах допустимо, но очень умеренно.
Заключение
Model View Controller (MVC) опыт использования, выводы
Недавно закончил свой первый проект, реализованный согласно концепции Model-View-Controller (MVC, хотя с технической точки зрения, правильнее было бы CMV). В статье предлагаю читателю познакомиться с моими личными впечатлениями от концепции.
Примечание
Все написанное в статье – это мое личное мнение. Вы, как читатель, не обязаны с ним соглашаться.
Цель статьи – ознакомить читателя с еще одним мнением, относительно распространенной концепции.
Мой путь к MVC
Некоторое время назад, мной было принято решение сделать свой блог. Повозившись какое-то время с WordPress пришел к выводу, что «там рыбы нет» (и сегодня, глядя на статистику запросов к сайту считаю, что отказ от WordPress было правильным решением). В общем, проанализировав совокупность внешних факторов (мои знания, необходимое время на разработку, доп. затраты на обслуживание и т. д.) решил все разработать самостоятельно, с нуля. И т. к. теперь у меня руки были развязаны (в выборе механизмов программной организации), решил опробовать «на себе» широко разрекламированную концепцию MVC (в предыдущих проектах я использовал модульный подход).
Мое понимание MVC
Недостатки концепции MVC
1. Необходимость использования большего количества ресурсов. Сложность обусловлена тем, что все три фундаментальных блока являются абсолютно независимыми и взаимодействуют между собой исключительно путем передачи данных. Controller должен всегда загрузить (и при необходимости создать) все возможные комбинации переменных и передать их в Model. Model, в свою очередь, должен загрузить все данные для визуализации и передать их во View. Например, в модульном подходе, модуль может напрямую обрабатывать переменные окружения и визуализировать данные без загрузки их в отдельные секции памяти.
2. Усложнен механизм разделения программы на модули. В концепции MVC наличие трех блоков (Model, View, Controller) прописано жестко. Соответственно каждый функциональный модуль должен состоять из трех блоков, что в свою очередь, несколько усложняет архитектуру функциональных модулей программы.
3. Усложнен процесс расширения функционала. Проблема очень схожа с вышеописанной. Недостаточно просто написать функциональный модуль и подключить его в одном месте программы. Каждый функциональный модуль должен состоять из трех частей, и каждая из этих частей должна быть подключена в соответствующем блоке.
Преимущества концепции MVC
1. Единая концепция системы. Несомненным плюсом MVC является единая глобальная архитектура приложения. Даже в сложных системах, разработчики (как те, которые разрабатывали систему, так и вновь присоединившиеся) могут легко ориентироваться в программных блоках. Например, если возникла ошибка в логике обработки данных, разработчик сразу отбрасывает 2-блока программы (controller и view) и занимается исследованием 3-го (model). Я не раз удивлялся, насколько сильно упростилась локализация проблем.
2. Упрощен механизм отладки приложения. Т. к. весь механизм визуализации теперь сконцентрирован в одном программном блоке, упростились механизмы опционального вывода графических элементов. Я не могу оценить насколько это утверждение применимо в программировании классических приложений, но в Web программировании эта архитектурная особенность стала несомненным плюсом.
Что такое MVC? Шаблон проектирования model view controller (MVC) и PHP, Часть 1
Шаблон проектирования Модель-Представление-Контроллер (model view controller — сокращенно MVC) — это шаблон программной архитектуры, построенный на основе сохранения представления данных отдельно от методов, которые взаимодействуют с данными.
Не смотря на то, что схема MVC была первоначально разработана для персональных компьютеров, она была адаптирована и широко используется веб-разработчиками из-за точного разграничения задач и возможности повторного использования кода. Схема стимулирует развитие модульных систем, что позволяет разработчикам быстро обновлять, добавлять или удалять функционал.
В этой статье я опишу основные принципы, а также рассмотрю определение схемы построения и простой MVC PHP пример.
Что такое MVC
Название шаблона проектирования определяется тремя его основными составляющими частями: Модель, Представление и Контроллер. Визуальное представление шаблона MVC выглядит, как показано на приведенной ниже диаграмме:
На рисунке показана структура одностороннего потока данных и пути его следования между различными компонентами, а также их взаимодействие.
Модель
Моделью называют постоянное хранилище данных, используемых во всей структуре. Она должна обеспечивать доступ к данным для их просмотра, отбора или записи. В общей структуре « Модель » является мостом между компонентами « Представление » и « Контроллер ».
Представление
Представление также перехватывает действие пользователя, которое затем передается « Контроллеру ». Характерным примером этого является кнопка, генерируемая « Представлением ». Когда пользователь нажимает ее, запускается действие в «Контроллере».
Существует несколько распространенных заблуждений относительно компонента « Представление ». Например, многие ошибочно полагают, что « Представление » не имеет никакой связи с « Моделью », а все отображаемые данные передаются от « Контроллера ». В действительности такая схема потока данных не учитывает теорию, лежащую в основе MVC архитектуры. В своей статье Фабио Чеваско описывает этот некорректный подход на примере одного из нетрадиционных MVC PHP фреймворков:
«Чтобы правильно применять архитектуру MVC, между «Моделью» и «Представлением» не должно быть никакого взаимодействия: вся логика обрабатывается «Контроллером».
Компоненту « Представление » никогда не передаются данные непосредственно « Контроллером ». Между « Представлением » и « Контроллером » нет прямой связи — они соединяются с помощью « Модели ».
Контроллер
Его задача заключается в обработке данных, которые пользователь вводит и обновлении « Модели ». Это единственная часть схемы, для которой необходимо взаимодействие пользователя.
« Контроллер » можно определить, как сборщик информации, которая затем передается в « Модель » с последующей организацией для хранения. Он не содержит никакой другой логики, кроме необходимости собрать входящие данные. « Контроллер » также подключается только к одному « Представлению » и одной « Модели ». Это создает систему с односторонним потоком данных с одним входом и одним выходом в точках обмена данными.
« Контроллер » получает задачи на выполнение только когда пользователь взаимодействует с « Представлением », и каждая функция зависит от взаимодействия пользователя с « Представлением ». Наиболее распространенная ошибка разработчиков заключается в том, что они путают « Контроллер » со шлюзом, поэтому присваивают ему функции и задачи, которые относятся к « Представлению ».
Также распространенной ошибкой является наделение « Контроллера » функциями, которые отвечают только за обработку и передачу данных из « Модели » в « Представление ». Но согласно структуре MVC паттерна это взаимодействие должно осуществляться между « Моделью » и « Представлением ».
MVC в PHP
У нас есть проект с несколькими основными классами для каждой части шаблона. Теперь нужно настроить взаимосвязь между ними:
В приведенном выше примере PHP MVC нет никакого специфического функционала для контроллера, потому что в приложении не определены взаимодействия пользователя. Представление содержит весь функционал, так как наш пример предназначен лишь для демонстрации.
Давайте расширим пример, чтобы показать, как мы будем добавлять функционал контроллера, тем самым добавив в приложение взаимодействия:
Мы расширили программу базовым функционалом. Настройка взаимодействий между компонентами теперь выглядит следующим образом:
Запустите код и при нажатии на ссылку вы увидите строку для изменения данных.
Заключение
Паттерны разработки: MVC vs MVP vs MVVM vs MVI
От переводчика: данная статья является переработкой английской статьи по паттернам разработки. В процессе адаптации на русский немало пришлось изменить. Оригинал
Выбор между различными паттернами разработки, всегда сопровождается рядом споров и дискуссий, а разные взгляды разработчиков на это еще больше усложняют задачу. Существует ли решение этой идеологической проблемы? Давайте поговорим о MVC, MVP, MVVM и MVI прагматично. Давайте ответим на вопросы: “Почему?”, “Как найти консенсус?”
Вступление
Вопрос выбора между MVC, MVP, MVVM и MVI коснулся меня, когда я делал приложение для Warta Mobile вместе с моей командой. Нам было необходимо продвинуться от минимально жизнеспособного продукта к проверенному и полностью укомплектованному приложению, и мы знали, что необходимо будет ввести какую-либо архитектуру.
У многих есть непоколебимое мнение насчет различных паттернов разработки. Но когда вы рассматриваете архитектуру, такую как MVC, то, казалось бы, полностью стандартные и определенные элементы: модель (Model), представление (View) и контроллер (Controller), разные люди описывают по разному.
Трюгве Реенскауг (Trygve Reenskaug) — изобрел и определил MVC. Через 24 года после этого, он описал это не как архитектуру, а как набор реальных моделей, которые были основаны на идее MVC.
Я пришел к выводу, что поскольку каждый проект — уникален, то нет идеальной архитектуры.
Необходимо детально рассмотреть различные способы реализации, и подумать над преимуществами и недостатками каждой.
Чего мы хотим добиться?
Масштабируемость, сопровождаемость, надежность
Очевидно, что масштабируемость (scalability) — возможность расширять проект, реализовывать новые функции.
Сопровождаемость (maintainability) — можно определить как необходимость небольших, атомарных изменений после того, как все функции реализованы. Например, это может быть изменение цвета в пользовательском интерфейсе. Чем лучше сопровождаемость проекта, тем легче новым разработчикам поддерживать проект.
Надежность (reliability) — понятно, что никто не станет тратить нервы на нестабильные приложения!
Разделение отвественности, повторное использование кода, тестируемость
Важнейшим элементом здесь является разделение ответсвенности (Separation of Concerns): различные идеи должны быть разделены. Если мы хотим изменить что-то, мы не должны ходить по разным участкам кода.
Без разделения ответственности ни повторное использование кода (Code Reusability), ни тестируемость (Testability) практически невозможно реализовать.
Ключ в независимости, как заметил Uncle Bob в Clean Architecture. К примеру, если вы используете библиотеку для загрузки изображений, вы не захотите использовать другую библиотеку, для решения проблем, созданных первой! Независимость в архитектуре приложения — частично реализует масштабируемость и сопровождаемость.
Model View Controller
У архитектуры MVC есть два варианта: контроллер-супервизор (supervising controller) и пассивное представление (passive view).
В мобильной экосистеме — практически никогда не встречается реализация контроллера-супервизора.
Архитектуру MVC можно охарактеризовать двумя пунктами:
Диаграмма иллюстрирует идеологию паттерна. Здecь, представление определяет как слушателей, так и обратные вызовы; представление передает вход в контроллер.
Контроллер принимает входные данные, а представление — выходные, однако большое число операций происходит и между ними. Данная архитектура хорошо подходит только для небольших проектов.
Пассивное представление MVC
Главная идея пассивного представления MVC — это то, что представление полностью управляется контроллером. Помимо этого, код четко разделен на два уровня: бизнес логику и логику отображения:
Massive View Controller
Нельзя трактовать Активити как представление (view). Необходимо рассматривать его как слой отображения, а сам контроллер выносить в отдельный класс.
А чтобы уменьшить код контроллеров представлений, можно разделить представления или определить субпредставления (subviews) с их собственными контроллерами. Реализация MVC паттерна таким образом, позволяет легко разбивать код на модули.
Однако, при таком подходе появляются некоторые проблемы:
Решение этих проблем кроется за созданием абстрактного интерфейса для представления. Таким образом, презентер будет работать только с этой абстракцией, а не самим представлением. Тесты станут простыми, а проблемы решенными.
Все это — и есть главная идея MVP.
Model View Presenter
Данная архитектура облегчает unit-тестирование, презентер (presenter) прост для написание тестов, а также может многократно использоваться, потому что представление может реализовать несколько интерфейсов.
С точки зрения того, как лучше и корректней создавать интерфейсы, необходимо рассматривать MVP и MVC только как основные идеи, а не паттерны разработки.
Use cases
Создание use cases — это процесс выноса бизнес логики в отдельные классы, делая их частью модели. Они независимы от контроллера и каждый содержит в себе одно бизнес-правило. Это повышает возможность многократного использования, и упрощает написание тестов.
В примере на GitHub, в login controller, вынесен use case валидации и use case логина. Логин производит соединение с сетью. Если есть общие бизнес правила в других контроллерах или презентерах, можно будет переиспользовать эти use case’ы.
Привязывание представления (View Bindings)
В реализации MVP есть четыре линейный функции, которые ничего не делают, кроме небольших изменений в пользовательском интерфейсе. Можно избежать этого лишнего кода, использовав view binding.
Все способы биндинга можно найти здесь.
Здесь простой подход: легко тестировать, и еще легче представить элементы представления как параметры через интерфейс, а не функции.
Стоит отметить, что с точки зрения презентера — ничего не изменилось.
Model View View-Model
Существует другой способ биндинга: вместо привязывания представления к интерфейсу, мы привязываем элементы представления к параметрам view-модели — такая архитектура называется MVVM. В нашем примере, поля email, password, и разметка определены с помощью связываний. Когда мы меняем параметры в нашей модели, в разметку тоже вносятся изменения.
ViewModel’и просты для написания тестов, потому что они не требуют написания mock-объектов — потому что вы меняете свой собственный элемент, а потом проверяете как он изменился.
Model View Intent
Еще один элемент, который можно ввести в архитектуре, обычно называется MVI.
Если взять какой-либо элемент разметки, например кнопку, то можно сказать, что кнопка ничего не делает, кроме того, что производит какие-либо данные, в частности посылает сведения о том что она нажата или нет.
В библиотеке RxJava, то, что создает события — называется observable, то есть кнопка будет являться observable в парадигме реактивного программирования.
А вот TextView только отображает какой-либо текст и никаких данных не создает. В RxJava такие элементы, которые только принимают данные, называются consumer.
Также существуют элементы, которые делают и то и то, т. е. и принимают и отправляют информацию, например TextEdit. Такой элемент одновременно является и создателем (producer) и приемником (receiver), а в RxJava он называется subject.
При таком подходе — все есть поток, и каждый поток начинается с того момента, как какой-либо producer, начинает испускать информацию, а заканчивается на каком-либо receiver, который, в свою очередь, информацию принимает. Как результат, приложение можно рассматривать как потоки данных. Потоки данных — главная идея RxJava.
Заключение
Несмотря на то, что внедрение разделения ответсвенности требует усилий, это хороший способ повысить качество кода в целом, сделать его масштабируемым, легким в понимании и надежным.
Другие паттерны, такие как MVVM, удаление шаблонного кода, MVI могут еще сильнее улучшить масштабируемость, но сделают проект зависимым от RxJava.
Также, следует помнить, что можно выбрать всего лишь часть из этих элементов, и сконфигурировать для конечного приложения в зависимости от задач.
Spring MVC — основные принципы
Фреймворк Spring MVC обеспечивает архитектуру паттерна Model — View — Controller (Модель — Отображение (далее — Вид) — Контроллер) при помощи слабо связанных готовых компонентов. Паттерн MVC разделяет аспекты приложения (логику ввода, бизнес-логику и логику UI), обеспечивая при этом свободную связь между ними.
DispatcherServlet
Вся логика работы Spring MVC построена вокруг DispatcherServlet, который принимает и обрабатывает все HTTP-запросы (из UI) и ответы на них. Рабочий процесс обработки запроса DispatcherServlet’ом проиллюстрирован на следующей диаграмме:
Ниже приведена последовательность событий, соответствующая входящему HTTP-запросу:
Конфигурирование
Вам будет необходимо связать (замапить) запросы, которые Вы хотите обработать при помощи DispatcherServlet, используя мапинг URL в файле web.xml. Ниже приведён пример объявления и мапинга DispatcherServlet’а HelloWeb:
Файл web.xml будет находиться в каталоге WebContent/WEB-INF. После инициализации HelloWeb, фреймворк попытается загрузить контекст приложения из файла с именем [servlet-name]-servlet.xml, находящегося в каталоге WebContent/WEB-INF. В нашем случае, это будет HelloWeb-servlet.xml.
Далее, тэг указывает, какие веб-адреса обрабатываются каким DispatcherServlet’ом. В нашем случае, все HTTP-запросы, заканчивающиеся на «.jsp», будут обработаны HelloWeb.
Если Вы не хотите использовать [servlet-name]-servlet.xml / WebContent/WEB-INF в качестве файла и директории по умолчанию, Вы можете настроить имя файла и директорию, добавив слушатель сервлета (servlet listener) ContextLoaderListener в web.xml, как показано ниже:
Теперь давайте проверим конфигурацию для HelloWeb-servlet.xml, размещённую в каталоге WebContent/WEB-INF:
Ниже приведены важные моменты в HelloWeb-servlet.xml:
Определение Контроллера
DispatcherServlet отправляет запрос контроллерам для выполнения определённых функций. Аннотация @Controllerannotation указывает, что конкретный класс является контроллером. Аннотация @RequestMapping используется для мапинга (связывания) с URL для всего класса или для конкретного метода обработчика.
Аннотация Controller определяет класс как Контроллер Spring MVC. В первом случае, @RequestMapping указывает, что все методы в данном Контроллере относятся к URL-адресу «/hello». Следующая аннотация @RequestMapping(method = RequestMethod.GET) используется для объявления метода printHello() как дефолтного метода для обработки HTTP-запросов GET (в данном Контроллере). Вы можете определить любой другой метод как обработчик всех POST-запросов по данному URL-адресу.
Вы можете написать вышеуказанный Контроллер по-другому, указав дополнительные атрибуты для аннотации @RequestMapping следующим образом:
Атрибут «value» указывает URL, с которым мы связываем данный метод (value = «/hello»), далее указывается, что этот метод будет обрабатывать GET-запросы (method = RequestMethod.GET). Также, нужно отметить важные моменты в отношении приведённого выше контроллера:
Создание Вида (JSP)
Spring MVC поддерживает множество типов Видов для различных технологий отображения страницы. В том числе — JSP, HTML, PDF, Excel, XML, Velocity templates, XSLT, JSON, каналы Atom и RSS, JasperReports и проч. Но чаще всего используются шаблоны JSP, написанные при помощи JSTL.
Давайте напишем простой Вид «hello» в /WEB-INF/hello/hello.jsp:
В данном случае, переменная $ выводит тот самый атрибут, установленный нами в Контроллере. Внутри Вида Вы можете отобразить любое количество атрибутов.
Примеры реализации фреймворка Spring MVC
Основываясь на приведённых выше концепциях, предлагаю выполнить несколько важных уроков, которые в дальнейшем помогут нам создавать приложения Spring Web:
Spring MVC Hello World Example
Пример, разъясняющий написание простейшего приложения Hello World.
Spring MVC Form Handling Example
В этом примере объясняется, как написать приложение Spring Web с помощью форм HTML, отправить данные контроллеру и отобразить обработанный результат.
Spring Static Pages Example
Получаем доступ к статическим страницам вместе с динамическими.