View в MVC


Оглавление (нажмите, чтобы открыть):

Паттерн MVC

Термин используется с конца 70-х гг. прошлого столетия. Эта модель явилась результатом проекта Smalltalk в компании Xerox PARC, где она была задумана как способ организации некоторых из ранних приложений графического пользовательского интерфейса. Некоторые из нюансов первоначальной модели MVC были связаны с концепциями, специфичными для Smalltalk, такими как экраны и инструменты, но более глобальные понятия все еще применимы к приложениям, и особенно хорошо они подходят для веб-приложений (MVC нашел отличное применение в ASP.NET, но ниже мы рассмотрим этот паттерн в WPF).

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

Модели

Содержат или представляют данные, с которыми работают пользователи. Они могут быть простыми моделями представлений, которые только представляют данные, передаваемые между представлениями и контроллерами; или же они могут быть моделями предметной области, которые содержат бизнес-данные, а также операции, преобразования и правила для манипулирования этими данными.

Представления

Применяются для визуализации некоторой части модели в виде пользовательского интерфейса.

Контроллеры

Обрабатывают поступающие запросы, выполняют операции с моделью и выбирают представления для визуализации пользователю.

Ниже структура MVC показана на диаграмме:

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

Уровень представления

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

Бизнес-уровень

Бизнес-уровень или, если говорить проще, уровень приложения, обеспечивает логику взаимодействия представления и данных. В MVC бизнес-уровень реализует структуру модели.

Уровень данных

Уровень данных отвечает за получение, передачу и сохранение данных в файле, базе данных, службе или XML.

Данная структура представлена ниже на рисунке:

Итак, давайте продемонстрируем реализацию паттерна MVC на простом приложении WPF, разделив его на три части — модель, представление и контроллер.

Модель

Создайте новый проект WPF в Visual Studio, добавьте ссылку на сборку ProjectBilling.DataAccess, которая рассматривалась в предыдущей статье, добавьте класс ProjectsModel со следующим содержимым:

Этот код создает модель для использования нашим представлением. Представление получает обновления из модели и через контроллер передает данные обратно в модель используя ссылку на IProjectsModel. Мы создали класс ProjectsModel реализующий IProjectsModel для возможности легкой расширяемости и тестируемости приложения. Давайте рассмотрим этот код более подробно. Интерфейс IProjectsModel содержит следующие члены, необходимые для реализации в классе:

Projects — свойство, содержащее коллекцию проектов, загружаемых из кода доступа к данным.

ProjectUpdated — это событие для уведомления экземпляра класса Project об обновлении.

UpdateProject — метод представления проекта, который будет обновляться.

Класс модели соответственно реализует данный интерфейс добавляя простейшую функциональность.

Контроллер

Следующий код был добавлен в файл ProjectsController.cs и реализует функциональность контроллера:

Мы реализовали контроллер на основе интерфейса IProjectsController, включающего два метода. ShowProjectsView — метод позволяющий отображать представление (реализованное классом ProjectsView) конечному пользователю. Update — метод обновления данных проекта, который вызывает прототип IProjectsModel.

Представление

Представление реализовано в файлах ProjectView.xaml и ProjectView.xaml.cs:

Этот код создает простую форму, для отображения подробностей о проекте. Затем добавьте следующий код для ProjectsView.xaml.cs:

Этот код практически аналогичен рассмотренному коду в предыдущей статье, но при этом он добавляет взаимосвязь с моделью и контроллером. Чтобы отобразить работоспособность этого приложения давайте добавим код вызова этой формы из главного окна приложения, т.е. MainWindow, добавив следующий код в соответствующие файлы:

Этот код будет служить в качестве главного окна приложения и будет отображать представление ProjectsView каждый раз, когда пользователь щелкает по кнопке Update. Давайте запустим это приложение и откроем два окна представления продукта:

Самое интересное в моделе MVC, что обновление распространяется через представления. Выполните следующие шаги чтобы это увидеть:

Выберите проект Jones в раскрывающемся списке ComboBox первого диалогового окна.

Установите актуальную стоимость для него 1600.

Щелкните кнопку Update в этом окне.

Вы должны увидеть автоматическое обновление представления во втором окне:

Можете поэкспериментировать с другими проектами или открыть еще несколько окон, при этом везде обновление представления будет работать так же. Итак, как видно MVC абстрагирует бизнес-логику от уровня представления, тем самым добиваясь легкой синхронизации пользовательского интерфейса. Я не буду рассматривать здесь модульное тестирование (еще один аспект использования паттернов) просто потому, что MVC больше подходит для веб-приложений, нежели для приложений WPF. Тестирование будет показано позже с использованием паттерна MVVM.

Model-View-Controller в .Net

Model-View-Presenter и сопутствующие паттерны


Автор: Иван Бодягин
The RSDN Group
Источник: RSDN Magazine #2-2006

Опубликовано: 25.07.2006
Исправлено: 10.12.2020
Версия текста: 1.1

Введение

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

«Оригинальный» MVC

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

Впервые паттерн MVC появился в языке SmallTalk в конце семидесятых. Собственно задача была хорошо всем знакомая, надо было придумать архитектурное решение, которое позволяло бы манипулировать графическими представлениями данных некоего приложения, таким образом, чтобы изменение Представления этих данных не влияло на бизнес-логику и данные ( Модель ) приложения, а так же, чтобы была возможность иметь несколько Представлений для одной Модели . Таким решением и стал паттерн MVC, идея которого родилась в недрах Xerox PARK, и получила свое первое публичное упоминание в документации к SmallTalk’80. В классическом варианте, MVC состоит из трех частей, которые и дали ему название.

Model (Модель)

Под Моделью , обычно понимается часть содержащая в себе функциональную логику приложения, иными словами то, что мы обычно называем «Business Layer», «Бизнес-слой» или «Слой бизнес логики». Как именно организован этот слой, по большому счету не важно, однако есть ряд ключевых моментов, на которых мы остановимся позднее. Основная цель паттерна — сделать так, чтобы Модель была полностью независима от остальных частей и практически ничего не знала об их существовании, что позволило бы менять и Контроллер и Представление модели, не трогая саму Модель и даже позволить функционирование нескольких экземпляров Представлений и Контроллеров с одной Моделью одновременно. Вследствии чего, Модель ни при каких условиях не может содержать ссылок на объекты Представления или Контроллера .

Обычно различают несколько типов паттернов в зависимости от роли модели.

Passive Model (пассивная модель) — Модель не имеет вообще никаких способов воздействовать на Представление или Контроллер и только используется ими в качестве источника данных для отображения. Все изменения модели отслеживаются Контроллером и он же отвечает за перерисовку Представления , если это необходимо.

Active Model (активная модель) — Модель имеет возможность оповестить Представление о том, что в ней произошли некие изменения, и Представление может эти изменения отобразить. Как правило, механизм оповещения реализуется на основе паттерна Observer (обозреватель), Модель просто бросает сообщение, а Представления , которые заинтересованы в оповещении, подписываются на эти сообщения, что позволяет сохранить независимость Модели как от Контроллера так и от Представления, не нарушая тем самым основного свойства паттерна. Классической реализацией паттерна MVC принято считать версию именно с активной Моделью .

СОВЕТ

Паттерн Observer (Обозреватель), известен так же под именем Publish/Subscribe (Публикатор/Подписчик), предназначен для организации наблюдения за состоянием объекта. Суть паттерна в том, что несколько объектов, называемых «обозревателями» или «слушателями» (listeners), регистрируются, сами или с чьей-либо помощью, в качестве обработчиков события (event), которое инициируется наблюдаемым объектом – «субъектом» (Subject) при изменении своего состояния. Таким образом достигается независимость «Субъекта» от «Обозревателей».

View (Представление)

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


Controller (Контроллер)

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

ПРИМЕЧАНИЕ

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

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

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

Следующим этапом развития MVC стал паттерн Document-View, хорошо известный по таким библиотекам как Turbo Vision (Pascal 6.0, ох ностальгия, Microsoft Foundation Class Library и многих других, вплоть до WinForms.

ПРИМЕЧАНИЕ

Строго говоря, утверждать, что эти библиотеки реализуют именно Document-View было бы не совсем верно, в конце-концов это всего лишь библиотеки и использовать их можно по разному, вернее было бы сказать, что эти библиотеки склоняют к использованию MVC именно в таком виде, как примерами из документации, так и собственной архитектурой.

В этой версии MVC Контроллер интегрирован в Представление , что ни в коей мере не является нарушением основной идеи паттерна. Сделано это было по многим причинам, прежде всего, отделение Контроллера от Представления , действительно не самая ключевая часть паттерна. Другой причиной являлось появление, графических оболочек встроеных в ОС, что позволяло не рисовать графические элементы (контролы) пользовательского интерфейса под каждый проект, а использовать готовые, предоставляемые платформой посредством соответствующего API, но дело в том, что в этих оболочках функции Контроллера уже были интегрированы в контролы (которые и являются Представлениями или же частями оного). Свою роль сыграло и появление визуальных графических оболочек встроеных в среду программирования (так называемые widget-based среды пользовательского интерфейса), поскольку код сгенеренный этими оболочками, естественно, использовал готовые графические элементы платформы и, как следствие, опять-таки провоцировал разработку в стиле Document-View. WinForms, в купе с Visual Studio, так же являются примером такой среды.

У той же Microsoft, которая выкладывает довольно много статей по архитектурным решениям в свободный доступ, есть несколько публикаций и по MVC, и там можно легко заметить, что все примеры чистого MVC даются не на основе WinForms приложений, а на примере ASP.NET, где, в отличии от WinForms, есть относительно четкое разделение между Контроллером и Представлением , про WinForms же есть только упоминание о том, что, как правило, в подобного рода приложениях Контроллер интегрирован в Представление .

Недостатки MVC и Document-View

В целом MVC и Document-View, как его логическое продолжение вполне адекватные паттерны для ряда задач, и с успехом применяются в большем количестве проектов, но в то же время обладают и рядом недостатков.

Прежде всего, чистый MVC плохо подходит для сред типа WinForms, поскольку, как уже говорилось выше, код, который порождают среды и библиотеки провоцирует интегрировать Контроллер в Представление . Получающийся в результате вариант паттерна в виде Document-View, в принципе, вполне приемлемое решение, однако далеко не всегда. Дело в том, что логика Контроллера , на самом деле, практически не зависит от типа Представления и сама по себе довольно неплохо поддается тестированию. А встраивание этой логики в Представление , в случае разных типов Представлений , приводит к дублированию кода и практически исключает возможность внятного тестирования этой логики, так как тестирование пользовательского интерфейса – это отдельная головная боль. Да и в целом, реализация логики контроллера вместе с представлением порождает довольно кашеобразную конструкцию из смеси автогенеренного и ручного кода Представления и кода логики Контроллера , который довольно сложно поддерживать. С появлением FW 2.0 и Partial-классов стало несколько легче, но проблема все равно актуальна.

Если же попытаться выделить Контроллер «в лоб», то можно нарваться на следующие неприятности.

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

Далее, выделя контроллер в его классическом варианте, можно столкнуться с недостатком связанным с особенностью роли Модели в классическом MVC. Как уже говорилось, MVC – это не просто паттерн, а набор паттернов, и Модель , в классическом MVC, на самом деле является медиатором (Mediator) между Контроллером/Представлением и реальной моделью домена (Domain Model) приложения (как это отражено на схеме).

СОВЕТ

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

В обязанности Медиатора входит транслировать вызовы Контроллера в нужные модели приложения и реализовать механизм оповещения Представлений , как правило посредством паттерна Обозреватель (Observer), о том, что нижележащая модель приложения изменилась. Таким образом, Модель должна обладать набором методов реализующих логику работы с пользовательским интерфейсом, однако сама Модель не может влиять напрямую на этот самый интерфейс (представления), в противном случае это убило бы саму идею паттерна, что приводит к необходимости реализации в Представлении логики обработки событий и, как следствие, «утолщению» Представления . Плюс к этому, в некоторых случаях хотелось бы дать пользователю возможность непосредственно влиять на Представление , без привлечения событийного механизма. Например, изменение цвета в некоторых Представлениях в классическом MVC выглядело бы так: в Контроллер попадает событие изменения цвета с кодом цвета, Контроллер вызывает соответствующий метод в Модели , в котором Модель выставляет нужный цвет и бросает событие о том, что в ней произошли изменения, затем данное событие перехватывается Представлениями и Представления перерисовываются, самостоятельно забрав у Модели новый цвет. Сам Контроллер не может отдать команду перерисоваться с нужным цветом, так как не умеет хранить состояние цвета и не знает каким Представлениям нужно передавать эту команду.

Таким образом нам нужна модификация паттерна которая, с учетом упомянутых недостатков, позволяла бы следующее:

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

Одним из возможных решений, отвечающим всем вышеприведенным требованиям, и является паттерн Model-View-Presenter (MVP).

Model-View-Presenter

Паттерн Model-View-Presenter, является очередной модификацией MVC. Если смотреть просто на схему, то визуально отличить его от MVC довольно сложно, поэтому лучше всего иллюстрировать его реализацию на кусочке реального кода. Код, конечно, реальный весьма относительно и довольно примитивен, однако надеюсь, вполне достаточнен для иллюстрации паттерна — мы попробуем реализовать программу, переводящую градусы цельсия в фаренгейты и наоборот, ну и, естественно, визуально это дело отображающую.

Model

Если бы мы разрабатывали наше приложение в привычном стиле, навязываемом WinForms, то скорее всего начали бы с набрасывания формочек, однако в данном случае мы зайдем с другой стороны и начнем с реализации Модели . И так, наша Модель должна уметь принимать данные температуры как в цельсиях так и в фаренгейтах и пересчитывать их в других величинах. Типичная Модель для данной задачи могла бы выглядеть следующим образом:

Presenter

Следующим этапом будет реализация Presenter -а, эта сущность заменяет Контроллер в классическом MVC — она делает все тоже самое, что и Контроллер , плюс кое-что еще. Более подробно о его функциях мы поговорим позже.

Presenter может иметь прямую ссылку на экземпляр Модели . В то же время Presenter должен иметь ссылку и на экземпляр или даже экземпляры Представления , которые будут отображать данные Модели . Однако здесь, в отличие от случая с Моделью , создание конкретного экземпляра конкретного класса Представления , может обернуться большими неудобствами. При наличии тесной связи между Presenter-ом и Представлением будет сложно реализовать замену Представлений и использование нескольких Представлений для одного Presenter-а , к тому же, это затруднит независимое тестирование Presenter-а. Да и в целом, наличие такой связи может привести к неправильной работе Presenter-а при изменении Представления , что совсем не хорошо.

Решить проблему зависимости Presenter-а от Представления можно с помощью паттерна Inversion of Control (он же Dependency Injection по Фаулеру) . Для этого мы создаем интерфейс Представления через который и будет осуществляться все взаимодействие с Представлениями .

СОВЕТ

Inversion of Control (IoC), это даже не паттерн, а архитектурный принцип, который используется для уменьшения связности между объектами. Суть его довольно проста. Допустим объект x (класс X) вызывает некий метод объекта y (класс Y), в этом случае считается, что X зависит от Y. Данная зависимость может быть «перевернута» путем введения третьего класса I, называемого интерфейсным классом, который содержит в себе все методы, которые x вызывает у объекта y, при этом Y должен реализовывать интерфейс I. После подобного преобразования X и Y зависят от I, но не зависят друг от друга, более того, если ранее X так же транзитивно зависил от всех классов от которых зависит Y, то теперь и эта зависимость оказалась разорвана.

Интерфейс Представления , в нашем случае, будет состоять из свойств для вывода посчитанных значений градусов цельсия и фаренгейта, ввода новых данных и событий оповещающих Presenter, что данные введены.

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

СОВЕТ

Паттерн Factory Method (фабричный метод), как и другие «строительные» паттерны, предназначен для создания объекта без указания конкретного класса реализующего этот объект. В данном случае это делается путем объявления в самом классе только публичного интерфейса для создания объекта, само же создание делегируется классам-наследникам.

Наличие интерфейса так же позволяет уже на этом этапе полностью завершить разработку Presenter-а и заняться его тестированием, несмотря на то, что конкретные Представления еще не готовы и ни один контрол еще не брошен на форму. ( И так, Presenter может выглядеть примерно следующим образом:

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

В данном случае реализовать интерфейс можно в классе реализующем форму, причем сделать это можно в отдельном проекте, вдруг потом захочется реализовать и web-интерфейс? ( Разработка конкретного Представления совсем тривиальна, форма представления наследуется от созданного нами ранее интерфейса, при этом реализация свойств интерфейса примитивна – по сути это просто перекладывание значений из интерфейса в контролы и наоборот.

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

Вот собственно и все, паттерн MVP в своем простейшем варианте перед вами, самое время его обсудить.

Почему интерфейс?

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

Строго говоря, сам паттерн вовсе не обязывает использовать для представления именно интерфейс, но использование здесь именно интерфейса, на мой взгляд, дает ряд преимуществ. Прежде всего, как и завещано создателями упоминавшегося принципа IoC, подобный подход уменьшает зависимость между классами. Замена интерфейса на некоторую базовую реализацию привела бы к тому, что изменение базовой реализации могло бы нарушить правильную работу использующего эту реализацию класса, в данном случае Presenter-а.

Помимо этого, использование интерфейса дает возможность делать Представление из объектов находящихся на любом уровне уже существующих иерархий, предоставляемых готовыми библиотеками. Например, в вышеприведенном случае, вполне можно было бы сделать базовую реализацию унаследовав ее от System.Windows.Forms , но дело в том, что конкретное Представление не обязательно может являться формой, с тем же успехом это может быть и контрол и даже произвольный класс, агрегирующий в себе графические элементы, а наследование от System.Windows.Forms жестко впишет базовый класс Представления в уже имеющуюся иерархию, и лишит подобной гибкости. Более того, с применением интерфейса Представление вообще может быть реализовано не в Win, а в Web-интерфейсе, реализовав, например, интерфейс IView от наследника System.Web.UI.Page. Очевидно, применение базовой реализации вместо интерфейса, как минимум, серьезно затруднило бы такой вариант использования Представлений .

Ну и, наконец, одной из особенностей данного паттерна является, так называемая, «скромность» Представления (humble view) по Фаулеру, то есть, в Представлении содержится вообще самый минимум логики, в некоторых источниках это так же называют «ультра тонкое» представление. Вследствии этого реализация интерфейса IView, как правило, крайне примитивна, чего собственно и добивались, декларируя необходимость вынесения максимального количества логики из Представления в Presenter.

Отличия от MVC

Чем же данный паттерн отличается от «классического» MVC и почему Controller назвали Presenter-ом?

Прежде всего, можно заметить, что, количество связей между сущностями уменьшилось, как правило, в MVP Модель не общается с Представлением даже опосредовано, через механизм оповещений, но это не обязательное условие, более глубокие отличия лежат как раз в области Presenter-а.

Как уже упоминалось выше, в MVC Модель , на самом деле, является медиатором, между Контроллером/Представлением и реальной моделью домена (Domain Model) приложения. В MVP-же, что видно на схеме, такого медиатора нет и его функции берет на себя Presenter, таким образом Presenter, в отличие от Контроллера , общается непосредственно с моделью приложения, а не с неким промежуточным звеном. Это позволяет, в случае необходимости, общаться Presenter-у с Представлениями , минуя Модель приложения и событийный механизм с этим связанный, так как Presenter в отличии от Контроллера , обладает необходимыми знаниями о Представлениях, а так же удаляет лишнюю логику обработки событий от Модели из Представления .

Отдельно стоит упомянуть совместимость с существующими оболочками и средами, что являлось одним из требований к MVP. В оригинальном MVC интерфейсом ко внешним событиям является Контроллер , однако большинство существующих библиотек и сред интегрируют эту функцию в Представление , провоцируя тем самым разработку в стиле Document-View. Этот момент обходится в MVP за счет того, что все нужные Presenter-у события описываются в интерфейсе Представления , и все необходимые события возниающие в Представлении просто пробрасываются в Presenter, что позволяет вынести из Представления логику их обработки.

Вследствии этого, как уже так же упоминалось, в отличии от MVC, Представление в MVP является «скромным» или «ультра-тонким» и практически не содержит логики независимой от конкретного Представления . Эту особенность, помимо всего прочего, очень любят маньяки от тестирования типа того же Фаулера, любители TDD, продвигатели XP и прочих Agile методологий, поскольку «скромные» представления сводят код не покрытый модульными тестами к минимуму.

Иными словами, если в случае MVC Контроллер играет довольно примитивную роль вызывальщика соответствующих методов Модели при реакции на событие, то Presenter в MVP уже берет на себя ведущие функции по управлению Моделями и Представлениями . Боюсь только, что данная особенность не нашла отражения в приведенном примере.

Заключение

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


Например, упомянутый здесь уже неоднократно Фаулер, выделяет аж три возможных модификации MVP, это Presentation Model, Supervising Controller и Passive View. Все они отличаются исключительно способом взаимодействия Presenter-а и Представления , а точнее способами передачи данных представлению. Если мы себе позволяем передавать в Представление бизнес-объекты, вместо примитивных типов, то это Presentation Model, если же позволили Представлению знать о наличии модели и самому забирать из нее данные, то это Supervising Controller, ну а самый простой случай, когда логика Представления действительно минимальна то с нами Passive View. В каждом конкретном случае выбор между этими тремя модификациями паттерна зависит от того, на сколько умную автоматическую привязку бизнес объектов к интерфейсу Представления вы можете использовать и какая степень покрытия тестами логики Presenter-а вас устроит. Ну и, само собой, от сложности бизнес-объектов и интерфейсов.

Для реальных ситуаций, которые, как правило, несколько сложнее приведенного примера, существуют модификации паттерна позволяющие выстроить определенную иерархию. Выделяют два варианта таких иерархических паттернов – это Hierarchical Model-View-Controller (HMVC) и Presentation-Abstraction-Control (PAC), который пришел из мира Java. Отличие заключается в том, что HMVC позволяет выстраивать независимые иерархии, отдельно для Представлений , отдельно для Контроллера /Presenter-а, ну и само-собой для Модели, с прямыми ссылками между собой, то есть, например, Представление может ссылаться непосредственно на дочернее Представление . В свою очередь PAC, более строгий паттерн, и предписывает иметь связи между собой только Контроллерам , другие сущности доступны извне исключительно через свой Контроллер .

В целом, применение MVP, вместо уже ставшего традиционным Document-View, с одной стороны, несколько увеличивает объем ручного кодирования, однако с другой, позволяет покрыть большую часть логики тестами, уменьшает связность между компонентами и может служить основой для реализации механизма «скинов» (оболочек, шкурок) приложения, вплоть до того, что для одного и того же «движка», можно иметь как Win, так и Web «шкурку».

MVC — модель-представление-контроллер

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

Основ­ная цель при­ме­не­ния MVC состоит в раз­де­ле­нии дан­ных и биз­ нес-логики от визу­а­ли­за­ции (внеш­него вида). За счет такого раз­де­ле­ния повы­ша­ется воз­мож­ность повтор­ного исполь­зо­ва­ния про­грамм­ного кода и упро­ща­ется сопро­вож­де­ние (изме­не­ния внеш­него вида, напри­мер, не отра­жа­ются на биз­ нес-логике ).

Кон­цеп­ция MVC раз­де­ляет дан­ные, пред­став­ле­ние и обра­ботку дей­ствий поль­зо­ва­теля на ком­по­нен­ты:

  • Модель (Model) — предо­став­ляет собой объ­ект­ную модель некой пред­мет­ной обла­сти, вклю­чает в себя дан­ные и методы работы с этими дан­ны­ми, реа­ги­рует на запросы из кон­трол­ле­ра, воз­вра­щая дан­ные и/или изме­няя своё состо­я­ние, при этом модель не содер­жит в себе инфор­ма­ции, как дан­ные можно визу­а­ли­зи­ро­вать, а также не «обща­ется» с поль­зо­ва­те­лем напря­мую.
  • Пред­став­ле­ние (View) — отве­чает за отоб­ра­же­ние инфор­ма­ции (визу­а­ли­за­цию), одни и те же дан­ные могут пред­став­ляться раз­лич­ными спо­со­ба­ми, напри­мер, кол­лек­цию объ­ек­тов при помощи раз­ных «вьюх» можно пред­ста­вить как в таб­лич­ном виде, так и спис­ком.
  • Кон­трол­лер (Controller) — обес­пе­чи­вает связь между поль­зо­ва­те­лем и систе­мой, исполь­зует модель и пред­став­ле­ние для реа­ли­за­ции необ­хо­ди­мой реак­ции на дей­ствия поль­зо­ва­теля, как пра­ви­ло, на уровне кон­трол­лера осу­ществ­ля­ется филь­тра­ция полу­чен­ных дан­ных и авто­ри­за­ция (про­ве­ря­ются права поль­зо­ва­теля на выпол­не­ние дей­ствий или полу­че­ние инфор­ма­ции).

Аль­тер­на­тив­ные назва­ния пат­терна MVC:

  • model-view-controller
  • модель-пред ­став­ле­ ние-пове ­де­ние
  • модель-пред ­став­ле­ ние-кон ­трол­лер
  • модель-вид-кон ­трол­лер

Шаблон проектирования MVC и PHP, Часть 1

Шаблон проектирования Модель-Представление-Контроллер (MVC) — это шаблон программной архитектуры, построенный на основе сохранения представления данных отдельно от методов, которые взаимодействуют с данными.

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

В этой статье я опишу основные принципы, а также рассмотрю определение схемы построения и простой MVC PHP пример.

Что такое MVC

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

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

Модель

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

При этом « Модель » не имеет никакой связи или информации о том, что происходит с данными, когда они передаются компонентам « Представление » или « Контроллер ». Единственная задача « Модели » — обработка данных в постоянном хранилище, поиск и подготовка данных, передаваемых другим составляющим MVC .

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

Представление

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

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

Существует несколько распространенных заблуждений относительно компонента « Представление ». Например, многие ошибочно полагают, что « Представление » не имеет никакой связи с « Моделью », а все отображаемые данные передаются от « Контроллера ». В действительности такая схема потока данных не учитывает теорию, лежащую в основе MVC архитектуры. В своей статье Фабио Чеваско описывает этот некорректный подход на примере одного из нетрадиционных MVC PHP фреймворков:

«Чтобы правильно применять архитектуру MVC, между «Моделью» и «Представлением» не должно быть никакого взаимодействия: вся логика обрабатывается «Контроллером».

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

Компоненту « Представление » никогда не передаются данные непосредственно « Контроллером ». Между « Представлением » и « Контроллером » нет прямой связи — они соединяются с помощью « Модели ».

Контроллер

Его задача заключается в обработке данных, которые пользователь вводит и обновлении « Модели ». Это единственная часть схемы, для которой необходимо взаимодействие пользователя.

« Контроллер » можно определить, как сборщик информации, которая затем передается в « Модель » с последующей организацией для хранения. Он не содержит никакой другой логики, кроме необходимости собрать входящие данные. « Контроллер » также подключается только к одному « Представлению » и одной « Модели ». Это создает систему с односторонним потоком данных с одним входом и одним выходом в точках обмена данными.

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

Также распространенной ошибкой является наделение « Контроллера » функциями, которые отвечают только за обработку и передачу данных из « Модели » в « Представление ». Но согласно структуре MVC паттерна это взаимодействие должно осуществляться между « Моделью » и « Представлением ».

MVC в PHP

Напишем на PHP веб-приложение, архитектура которого основана MVC . Давайте начнем с примера каркаса:

У нас есть проект с несколькими основными классами для каждой части шаблона. Теперь нужно настроить взаимосвязь между ними:

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

Давайте расширим пример, чтобы показать, как мы будем добавлять функционал контроллера, тем самым добавив в приложение взаимодействия:

Мы расширили программу базовым функционалом. Настройка взаимодействий между компонентами теперь выглядит следующим образом:

Запустите код и при нажатии на ссылку вы увидите строку для изменения данных.

Заключение

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

Данная публикация представляет собой перевод статьи « The MVC Pattern and PHP. Part 1 » , подготовленной дружной командой проекта Интернет-технологии.ру

View в MVC

Концепция MVC была описана в 1979 году [2] Трюгве Реенскаугом (англ. Trygve Reenskaug ), тогда работающим над языком программирования Smalltalk в Xerox PARC. Оригинальная реализация описана в статье «Applications Programming in Smalltalk-80: How to use Model-View-Controller» [3] . Затем Джим Алтофф с командой разработчиков реализовали версию MVC для библиотеки классов Smalltalk-80.

В оригинальной концепции была описана сама идея и роль каждого из элементов модели, представления и контроллера. Но связи между ними были описаны без конкретизации. Кроме того, различали две основные модификации:

  1. Пассивная модель — модель не имеет никаких способов воздействовать на представление или контроллер, и используется ими в качестве источника данных для отображения. Все изменения модели отслеживаются контроллером и он же отвечает за перерисовку представления, если это необходимо. Такая модель чаще используется в структурном программировании, так как в этом случае модель представляет просто структуру данных, без методов их обрабатывающих.
  2. Активная модель — модель оповещает представление о том, что в ней произошли изменения, а представления, которые заинтересованы в оповещении, подписываются на эти сообщения. Это позволяет сохранить независимость модели как от контроллера, так и от представления.

Классической реализацией концепции MVC принято считать версию именно с активной моделью.

С развитием объектно-ориентированного программирования и понятия о шаблонах проектирования был создан ряд модификаций концепции MVC, которые при реализации у разных авторов могут отличаться от оригинальной. Так, например, Эриан Верми в 2004 году описал пример обобщенного MVC [4] .

Назначение

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

  1. К одной модели можно присоединить несколько видов, при этом не затрагивая реализацию модели. Например, некоторые данные могут быть одновременно представлены в виде электронной таблицы, гистограммы и круговой диаграммы.
  2. Не затрагивая реализацию видов, можно изменить реакции на действия пользователя (нажатие мышью на кнопке, ввод данных), для этого достаточно использовать другой контроллер.
  3. Ряд разработчиков специализируется только в одной из областей: либо разрабатывают графический интерфейс, либо разрабатывают бизнес-логику. Поэтому возможно добиться того, что программисты, занимающиеся разработкой бизнес-логики (модели), вообще не будут осведомлены о том, какое представление будет использоваться.

Концепция


Концепция MVC позволяет разделить данные, представление и обработку действий пользователя на три отдельных компонента:

  • Модель (англ.Model ). Модель предоставляет знания: данные и методы работы с этими данными, реагирует на запросы, изменяя своё состояние. Не содержит информации, как эти знания можно визуализировать.
  • Представление, вид (англ.View ). Отвечает за отображение информации (визуализацию). Часто в качестве представления выступает форма (окно) с графическими элементами.
  • Контроллер (англ.Controller ). Обеспечивает связь между пользователем и системой: контролирует ввод данных пользователем и использует модель и представление для реализации необходимой реакции.

Важно отметить, что как представление, так и контроллер зависят от модели. Однако модель не зависит ни от представления, ни от контроллера. Тем самым достигается назначение такого разделения: оно позволяет строить модель независимо от визуального представления, а также создавать несколько различных представлений для одной модели.

Для реализации схемы Model-View-Controller используется достаточно большое число шаблонов проектирования (в зависимости от сложности архитектурного решения), основные из которых «наблюдатель», «стратегия», «компоновщик» [5] .

Наиболее типичная реализация отделяет вид от модели путем установления между ними протокола взаимодействия, используя аппарат событий (подписка/оповещение). При каждом изменении внутренних данных в модели она оповещает все зависящие от неё представления, и представление обновляется. Для этого используется шаблон «наблюдатель». При обработке реакции пользователя вид выбирает, в зависимости от нужной реакции, нужный контроллер, который обеспечит ту или иную связь с моделью. Для этого используется шаблон «стратегия», или вместо этого может быть модификация с использованием шаблона «команда». А для возможности однотипного обращения с подобъектами сложно-составного иерархического вида может использоваться шаблон «компоновщик». Кроме того, могут использоваться и другие шаблоны проектирования, например, «фабричный метод», который позволит задать по умолчанию тип контроллера для соответствующего вида.

Наиболее частые ошибки

Начинающие программисты (особенно в веб-программировании, где аббревиатура MVC стала популярна) очень часто трактуют архитектурную модель MVC как пассивную модель MVC. В этом случае модель выступает исключительно совокупностью функций для доступа к данным, а контроллер содержит бизнес-логику. В результате код моделей по факту является средством получения данных из СУБД, а контроллер представляет собой типичный модуль, наполненный бизнес-логикой, или скрипт в терминологии веб-программирования. В результате такого понимания MVC разработчики стали писать код, который Pádraic Brady, известный в кругах сообщества Zend Framework, охарактеризовал как ТТУК — «Толстые тупые уродливые контроллеры» (Fat Stup >[6] :

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

Но в объектно-ориентированном программировании используется активная модель MVC, где модель — это не только совокупность кода доступа к данным и СУБД, а вся бизнес-логика. В свою очередь, контроллеры представляют собой лишь элементы системы, в чьи непосредственные обязанности входит приём данных из запроса и передача их другим элементам системы. Только в этом случае контроллер становится «тонким» и выполняет исключительно функцию связующего звена (glue layer) между отдельными компонентами системы.

Пример контроллера MVC в рамках PHP5

Данный пример иллюстрирует реальный код контроллера на PHP5 в рамках объектно-ориентированного приложения, построенного по концепции MVC. Здесь контроллер выступает в роли класса с единственным методом run() , который запускает Front-Controller. Цель контроллера — отдать в Представление (View) данные для формирования страницы со списком объявлений.

В начале с помощью метода контроллера getView() программист получает объект Представления (View), который вызывает методы, специфичные для Представления (View): метод loadI18n() с помощью которого в Представление (View) подгружаются файлы интернационализации, а также метод initTitle() , формирующий title HTML-страницы на основе данных, полученных в ходе разбора файлов интернационализации.

Далее через метод контроллера checkAccess() проверяется, имеет ли пользователь доступ к этой странице. Если доступ не разрешён, формируется предупреждение и происходит перенаправление на ресурс «/admin/». Далее инстанцируется Модель (Model), а точнее, один из компонентов модели — сервис Krugozor_Module_Advert_Service_List . Данный класс инкапсулирует логику получения массива объектов моделей на основе различных параметров из объекта запроса Request , а также взаимодействует с объектом пагинации.

После получения данных от сервиса в Представление (View) передается массив моделей adverts , объект пагинации pagination , идентификатор запрошенной в URL-адресе категории id_category и идентификатор пользователя id_user , после чего Представление (View) отдается во Front-Controller для дальнейшего действия (шаблонизации и вывод в выходной поток).

В примере явно видно, что Контроллер представляет собой связующее звено между двумя основными компонентами системы — Моделью (Model) и Представлением (View). Модель ничего «не знает» о Представлении, а Контроллер не содержит в себе какой-либо бизнес-логики.

Программа Model-View-Controller MVC — что это, особенности и описание

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

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

Основные типы функциональности архитектуры

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

  1. Код модели обычно отражает реальные вещи. Этот код может содержать необработанные данные или определять основные компоненты приложения. Например, если пользователь создавал приложение Todo, код модели определял бы, что такое «задача» и что такое «список», поскольку это основные компоненты данного приложения.
  2. Вид, или представление — просмотр кода состоит из всех функций, которые непосредственно взаимодействуют с пользователем. Это код, который делает приложение красивым и в противном случае определяет, как пользователь видит и взаимодействует с ним.
  3. Контроллер действует как связь между моделью и представлением, принимая пользовательский ввод и решая, что с ним делать. Это мозг приложения и связывает модель и представление. Контроллер считают «средним уровнем». Он взаимодействует с пользователем, собирая данные, контактирует с моделью, получая необходимые данные, а затем с представлением, чтобы ответить пользователю.

Когда пользователь выполняет какое-либо действие, он сначала переходит к контроллеру. Он будет принимать любые данные, например, $_GET, $_POST переменные в PHP, и определять, что делать с этими данными. Короче говоря, модели относятся к обработке данных и расширенной функциональности. Поэтому задача контроллера в этой точке состоит в том, чтобы определить, какую модель следует вызывать, а затем открыть соответствующую функцию внутри этой модели. После вызова функции он будет находить результат, обычно в переменной среде.

Модель – это простое представление о том, что пользователь выполняет в приложении. Модель MVC — это что должны представить в коде, например книги пользователя, его банковского счета или чего-то еще. Модель отвечает за хранение функций и переменных, которые связаны с тем, что она представляет.

Можно думать о логике модели как о базовой концепции объектно-ориентированного программирования. Тут модели — это просто «классы». Не стоит путать с классами в контроллерах, которые технически тоже структурированы как классы. Наконец, после того как контроллер запрашивает информацию из модели, она отправляет ее в представление.

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

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

Структура организации кода

Большая идея MVC заключается в том, что каждая часть кода имеет свою цель, и эти цели различны. Некоторые из кодов содержат данные приложения, некоторые делают приложение приятным, а некоторые из них контролируют функциональность.

Считается, что это MVC, программа, которая способна организовать основные функции кода в свои, аккуратно организованные ящики. Структура файла для использования MVC стандартным образом довольно проста — есть просто папки для представлений, моделей и контроллеров, и все они связаны друг с другом через один каталог. Конечно, с любым веб-приложением у пользователя также будут другие папки и файлы, такие как индексный файл и папка для изображений.

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

Структура ASP.NET Core MVC — это легкая среда представления. Отличается открытым исходным кодом. Она высоко проверяемая, оптимизированная для использования с Asp Net Core MVC.

Архитектура MVC

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

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

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

Аналогия модели в современном мире

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

Модель в приложении ToDo может определить что «задача» есть и что «список» представляет собой набор задач. Код View определит, как выглядят ToDo и списки визуально. Задачи могут иметь большой шрифт или быть определенного цвета. Наконец, контроллер может определить, как пользователь добавляет задание или отмечает, когда оно завершено. Контроллер соединяет кнопку «Добавить» в «Модель» поэтому, когда пользователь нажимает «Добавить задачу», модель добавляет новую задачу.

Просто о шаблоне проектирования

Возможности MVC приложения можно показать в двух словах, на примере адресной книги. Модель представляет собой список Person объектов. Представление представляет собой окно графического интерфейса пользователя, которое отображает список людей. А контроллер обрабатывает такие действия, как «Удалить адрес человека», «Добавить адрес человека», «Электронная почта человека».

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

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

Основные зависимости элементов

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

В настоящее время существует три класса:

  1. Person.
  2. PersonListController.
  3. PersonListView.

Необходимо создать два класса: PersonPhotoGridView и PersonPhotoGridController. Person класс остается тем же самым и легко вставляется в две различные точки зрения. Разработчик должен модифицировать Person класс для размещения нового PersonPhotoGridView и в конечном итоге усложняет модель (пример 3).

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

В setPicture этот момент метода является в основном кодом спагетти. Шаблон проектирования MVC вставляет класс контроллера между представлением и моделью, чтобы удалить зависимости модели. При удалении зависимостей модель и, возможно, вид могут быть сделаны повторно используемыми без изменений. Это делает внедрение новых функций и техническое обслуживание легкими. Пользователи быстро получают стабильное программное обеспечение, компания экономит деньги, а разработчики работают в нормальных условиях.

Принцип работы

Принцип MVC состоит в том, чтобы разделить приложение на 3 основные части, известные как Модель, Вид (просмотр) и Контроллер. Видимыми на диаграмме являются прямые ассоциации (красные стрелки) и выведенные ассоциации (голубые стрелки). Выведенные ассоциации — это те, которые могут казаться очевидными с точки зрения пользователя, а не исходя из фактического дизайна программного обеспечения.

Простой способ выполнения условия:

  1. Пользователь взаимодействует с представлением — нажатием на ссылку или отправкой формы.
  2. Контроллер обрабатывает ввод пользователя и передает информацию в модель.
  3. Модель получает информацию и обновляет ее состояние, добавляет данные в базу данных, например, вычисляет сегодняшнюю дату.
  4. Просмотр проверяет состояние Модели и отвечает соответственно, перечислив недавно введенные данные.
  5. Вид ожидает следующего взаимодействия пользователя.


Это простая концепция — Business Logic — вычисления логических процессов приложения. Например, бизнес-логика простого календаря должна была бы рассчитать, какая дата, какой день недели и какой день месяца, если нужно представить все дни в этом месяце. Или осуществлять обслуживание веб-контента с помощью Spring MVC, которая дает возможность строить приложение со статической домашней страницей, принимающей запросы HTTP GET.

Соблюдение принципа DRY

Многие фреймворки MVC используют систему шаблонов для обеспечения соблюдения принципа DRY, что делает его очень удобным для повторного использования кода без необходимости переписывания. Существуют рамки MVC, которые работают на Smarty или используют собственные механизмы шаблонов. Простым предупреждением является то, что некоторые движки шаблонов имеют довольно сложный синтаксис – программисту требуется проверить их, прежде чем начинать разработку.

Считается, что MVC – это еще одна очень хорошая реализация философии DRY (Do not Repeat Yourself). По сути, DRY используется Ruby on Rails и несколькими другими реализациями, а идея состоит в том, что программист пишет что-то один раз и один раз использует код. Принцип DRY определяется как «каждая часть должна иметь единое, однозначное, авторитетное представление внутри системы». Правильная реализация DRY означает, что изменение одного элемента системы не изменяет несвязанные элементы, что довольно логично.

Конвенция по конфигурации

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

Также можно установить все методы формы в POST, если не указано иное. Применение этой идеи ко всем элементам делает создание такого типа приложения очень быстрым, простым и понятным. MVC — это действительно хороший способ начать производство чистого, масштабируемого, мощного и быстрого кода за меньшее время с минимальными затратами усилий. Некоторые структуры MVC не содержат всех этих функций, большинство из них содержат только один или два.

Преимущества и недостатки метода

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

  1. Быстрый процесс разработки, поддерживает быстрое и параллельное развитие.
  2. С MVC один программист может работать над представлением, а другой может работать над контроллером для создания бизнес-логики.
  3. Приложение, разработанное с его применением, в три раза быстрее, чем приложение, разработанное с другими шаблонами разработки.
  4. Возможность предоставления нескольких видов.
  5. В MVC можно создавать несколько представлений.
  6. Копирование дубликатов очень ограничено, поскольку оно отделяет данные и логику от дисплея.
  7. Поддержка асинхронной технологии, которая помогает разработчикам разрабатывать быстро загружаемое приложение.
  8. Модификация не влияет на всю модель, потому что часть модели не зависит от части просмотров. Поэтому любые изменения в Модели не будут влиять на всю архитектуру.
  9. Шаблон NET MVC возвращает данные без применения какого-либо форматирования, поэтому одни и те же компоненты могут использоваться и вызываться для использования с любым интерфейсом.
  10. С помощью этой платформы очень легко разрабатывать URL-адреса, оптимизированные для SEO, для получения большего количества посещений из определенного приложения.
  1. Повышенная сложность.
  2. Неэффективность доступа к данным.
  3. Сложность использования MVC с современным пользовательским интерфейсом.
  4. Нужно несколько программистов.
  5. Требуется знание нескольких технологий. Разработчик знает код клиентской стороны и html-код.

Создание первого приложения

Можно разработать примеры ASP.NET MVC с соответствующей версией среды Visual Studio и .NET, используя MVC v5.2, 2020 Community и платформу .NET 4.6.

  1. Открыть программу Visual Studio 2020 и далее: Файл -> Создать > Проект.
  2. Разворачивают узел Visual C # и Web в левой части и далее выбирают asp net MVC в средней части.
  3. Вводят название своего проекта MyMVCApplication, можно указать любое подходящее имя для своего приложения.
  4. Устанавливают местоположение проекта, нажав «Обзор» и далее «ОК».
  5. В окне «Новое веб-приложение» находят asp MVC core.
  6. Изменяют аутентификацию, нажав соответствующую кнопку.
  7. Нажимают «ОК», чтобы MVC создал проект с использованием шаблона.
  8. Первое приложение готово.

Запускают проект в режиме отладки F5 или Ctrl + F5 без отладки.

Проект MVC framework включает JavaScript и файлы CSS bootstrap 3.0 по умолчанию.

Таким образом можно создавать отзывчивые веб-страницы. Этот отзывчивый пользовательский интерфейс изменит его внешний вид на основе размера экрана различных устройств.

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

Таким образом, легко создать свое первое приложение core MVC с помощью Visual Studio 2013.

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

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

MVC php на пальцах?

Model View Controller. Да ну его, ему уже 45 лет (придумали в 79-ом году). Давайте лучше про Model View Adapter погокорим. это то что все используют в популярных фреймворках последние лет так 10 так точно.

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

View — это не только HTML, но и вообще представление в целом, а так же логика его формирования. Шаблонизаторы, фильтры, различные функции/объекты помогаютщие нам сформировать view (например форматирование дат, сериализаторы и т.д.) В подавляющем большинстве случаев «представление» наших данных — это HTTP запросы и HTTP ответы. HTML — э то лишь часть HTTP ответа.

Model — Это целый слой, который может быть представлен в виде кучи отдельных объектиков, структур и т.д. Его задача — делать дела и хранить/менять состояние системы. Тут легко запутаться потому что термин «модель» много чего значит. Воспринимайте его как «слой логики» а не конкретные объекты. И да — база данных и прочая чушь — это детали реализации этого слоя. «не важные штуки» словом. Туда же и ActiveRecord, ORM-ки всякие. Это деталь реализации и все остальные чуваки (view и controller) о них знать ничего не должны (хотя иногда могут в целях упрощения).

Controller или адаптер. Это опять же не обязательно один объект. это может быть цепочка адаптеров (еще называют фронт-контроллером, middlewares и т.д.). Его задача весьма простая. Получаем представление данных на входе (HTTP запрос), определяем что надо делать, и просим модель что-то сделать (ни в коем случае не меняем ничего самостоятельно в контроллере, он только просит). Потом мы можем попросить модель вернуть нужный нам кусок состояния, и попросить View сформировать представление (HTTP ответ).

Как-то так. В целом же это я сейчас описал «идеальный мир». Вся суть этого подхода — разделение логики презентационной и логики приложения. Зачем это надо? что бы было проще жить! Обычно UI приложения или способы взаимодействия с ним меняются почаще логики или как минимум в разные моменты времени. Адаптеры в этом случае служат промежуточным слоем, они ничего сами не делают, это «переводчики». Они просто переводят то, что сказано в запросе в язык понятный приложению и обратно.

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

Модель — это любая ваша бизнес-логика, всякие вычисления и запросы к бд. То есть то, без чего приложение впринципе не имеет смысла.

Контроллер — это посредник между моделью и видом. Он запрашивает данные (вызывает методы) у модели и затем передает их в вид.

Вид — с помощью полученных данных от контроллера рисует пользовательский интерфейс.

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

Нужна одна точка входа. Клиент всегда запрашивает только index.php, оно там внутри на основе данных из запроса решает какой контроллер создать и какой метод из контроллера выполнить. Всё.

xfg: контроллер не должен «создавать» модели, он их получает и может из только о чем-то просить.

В вашем примере LoginForm — это часть представления замэпленная на структурку, даже и не пахнет моделью (в крайнем случае это view model). Промежуточная структурка которая должна быть передана уже модели. Просто переносчик данных.

Yii плохой пример для демонстрации «принципов», так как там все концепции упрощены до нельзя.

Просто говоря MVC — физическое разделение кода на три основные логические части: Model, View, Controller с которыми мы обязуемся работать определенным образом в целях облегчения процесса разработки.

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

В отображениях (View) располагается так называемый «шаблон». Как правило это файлы с HTML версткой и PHP логикой отвечающей за отображения конкретных элементов. Например, тут нельзя делать запрос к БД, но можно написать цикл, который будет отображать блоки верстки с новостями.

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

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

Запрос попадает в нужный контроллер (контроллер постов). Он начинает собирать нужные данные:

  • Контроллер достает из настроек название сайта.
  • Контроллер обращается к модели отвечающей за посты, в ней содержатся различные методы, отвечающие за работу с постами (вывод списка постов, отображение одного поста, редактирование поста итп), каждый метод может делать различные запросы к БД и производить необходимые манипуляции с данными. В данном случае мы вызываем метод getPost() который получает id поста, делает выборку из БД и возвращает результат.
  • Данные из модели возвращается в контроллер. Если пост с переданным id не был найдет, именно контроллер перенаправит пользователя на страницу с кодом 404.
  • Но в нашем случае пост был найден и теперь контроллер берет из полученных данных название поста и обращается к модели ответственной за получение похожих публикаций, она на основе полученного названия возвращает массив из похожих названий статей и их id (все что нужно в нашем примере для отображения списка ссылок).
  • Контроллер собрал все что было нужно и теперь берет заданный нами файл шаблона отображения и передает туда все необходимые данные.
  • В отображении мы отображаем название сайта в тайтле, внутри верстки выводим наш пост, а по массиву похожих публикаций приходимся циклом отображая его как список ссылок.
  • Страница с постом успешно отображена.

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

Чтобы понять, что еще может делать каждая из частей и как вообще это выглядит, изучите документацию и примеры по одному из популярных PHP фреймворков, например, таких как Yii и Laravel.

Проектировочный шаблон Model-View-Presenter-ViewModel для WPF

Продукты и технологии:

Windows Presentation Foundation, Model-View-Controller, Model-View-ViewModel, Model-View-Presenter, Prism

В статье рассматриваются:

• проектировочный шаблон MVC;

• проектировочный шаблон MVP;

• проектировочный шаблон MVPVM;

• уровень бизнес-логики;

• уровень доступа к данным (data access layer, DAL);


• почему важно знать и понимать историю.

Исходный код можно скачать по ссылке amarillo.us.com/MSDN/MvpVmR2.zip.

Во всех успешных проектах, в которых я принимал участие, самыми успешными были те, в которых по мере увеличения приложения кодовая база становилась меньше. На первый взгляд такое утверждение может показаться противоречивым, но кодирование в Agile-среде уже само по себе ведет к сокращению кодовой базы. Когда требования изменяются, происходит рефакторинг, и эта возможность рефакторинга — в сочетании с ретроспективным подходом (hindsight) — обеспечивает более эффективное повторное использование существующих компонентов, попутно позволяя убирать дублирующийся код.

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

В этой статье я представлю один из таких шаблонов — Model-View-Presenter-ViewModel (MVPVM), который часто упускают из виду из-за популярности шаблона Model-View-ViewModel (MVVM) многие разработчики, использующие Windows Presentation Foundation (WPF). Этот проектировочный шаблон корпоративных приложений был введен в проекте Prism группой Microsoft Patterns & Practices (Prism.CodePlex.com). (Замечу, что у этого шаблона не было названия, поэтому я буду ссылаться на него как на MVPVM.) Prism можно лучше всего охарактеризовать цитатой из обзора на указанном веб-сайте:

«Prism помогает облегчить проектирование и создание функциональных, гибких и простых в сопровождении настольных WPF-приложений (Windows Presentation Foundation), а также Silverlight Rich Internet Applications (RIA) и приложений Windows Phone 7. Используя проектировочные шаблоны, которые охватывают важные архитектурные принципы проектирования, такие как разделение обязанностей и слабое связывание, Prism способствует разработке приложений на основе слабо связанных компонентов, развиваемых независимо, но легко и бесшовно интегрируемых в общее приложение. Такие приложения называют составными (composite applications)».

Популярность и успешность MVVM затмила MVPVM, хотя MVPVM является результатом эволюционного развития MVVM (как будет продемонстрировано в этой статье). MVPVM обеспечивает все, что может предложить MVVM, и добавляет масштабируемость и расширяемость шаблона Model-View-Presenter (MVP).

Прежде чем мы сможем в полной мере оценить мощь и преимущества MVPVM, нужно разобраться в том, как развивался этот шаблон, т. е. окунуться в историю. Важнейшим элементом, который поможет это понять, является шаблон Model-View-Controller (MVC), поэтому сначала мы обсудим MVC, и, возможно, вы увидите его таким, каким никогда раньше не представляли.

Шаблон MVC

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

В документе «GUI Architectures» за авторством Мартина Фаулера (Martin Fowler) (bit.ly/11OH7Y) об MVC написано следующее: «Разные люди, читая о MVC в разных источниках и черпая из них разные идеи, воспринимают все это как единое понятие — MVC. Будто одного этого недостаточно для путаницы, на вас потом воздействует еще и эффект испорченного телефона». В документе «Whatsa Controller Anyway» (bit.ly/7ajVeS) его точка зрения замечательно подытоживается: «Ученые в области компьютерных наук в целом склонны к раздражающей привычке перегружать термины разным смыслом. То есть за одним словом закрепляется более чем одно значение (и иногда эти значения прямо противоположны друг другу)».

Обсуждение MVC еще больше осложняется тем, что у разработчиков нет общего языка с великими архитекторами. Перегруженность терминов и эффект «испорченного телефона» усугубляются тем фактом, что большинство из нас даже не знает, что такое Controller, — ведь нам не приходится им пользоваться, потому что ОС всегда сама предоставляет его функциональность. Заполнив эти пробелы, мы обнаружим, что на самом деле MVC легко понять и что «C» в MVC не имеет ничего общего с «P» в MVP.

У Controller есть вполне конкретный источник (который стоит понимать, но он не обязательно соответствует современным подходам к MVC в контексте текущих технологий). Отец-основатель MVC, Трюгве Реенскауг (Trygve Reenskaug), написал об этом в 1979 г. в своем документе «Models-Views-Controllers» (bit.ly/2cdqiu). Этот документ проливает свет на некоторые цели Controller. Реенскауг писал:

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

Контроллер никогда не должен дополнять представления. И вы никогда не должны соединять представления узлов, рисуя стрелки между ними.

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

Эту концепцию иллюстрирует рис. 1.

Популярность и успешность MVVM затмила MVPVM, хотя MVPVM является результатом эволюционного развития MVVM.

Рис. 1. Контроллер принимает ввод и посылает сообщение (методу для выполнения); представления не могут захватывать пользовательский ввод

Сообщение в контексте объектно-ориентированного программирования (ООП) MVC является способом выполнения методов. Они описывались как сообщения потому, что в те годы виртуальные вызовы были новой концепцией и нужен был какой-то способ различать их с вызовами статических функций. В главе 1.2 книги «Smalltalk, an Introduction to Application Development Using VisualWorks» (Prentice Hall, 1995) авторы — Тревор Хопкинс (Trevor Hopkins) и Бернард Горан (Bernard Horan) — отмечают, что «…если принимающий объект понимает переданное ему сообщение, тогда будет выполнена одна из его внутренних операций (или методов). Это в свою очередь может вызвать выполнение каких-то вычислений (воздействуя на одну или более внутренних переменных объекта)». (Обратите внимание: эта ООП-концепция передачи сообщений доступна в Prism через EventAggregator.)

В главе 29 «Introduction to Models, Views and Controllers» той же книги были обрисованы задачи Smalltalk MVC, где мы узнавали, что контроллеры наследуют от класса Controller. В ней говорилось: «Экземпляры этого класса хранят ссылку на датчик (sensor), представляющий мышь и клавиатуру, поэтому они могут обрабатывать ввод». Далее сообщалось, что Controller инициирует две разные операции: взаимодействие с Model (см. рис. 1) и взаимодействие с View, не затрагивающее Model.

В Smalltalk MVC у каждого View есть Controller, причем в любой момент может быть активен только один Controller. В оригинальном Smalltalk MVC осуществлялся опрос UI: класс ControlManager верхнего уровня опрашивал каждый Controller активного View, требуется ли ему получить управление. И получить управление мог лишь тот View, который содержал курсор. Если View предназначен только для чтения, то на этот случай предусматривался класс NoController, рассчитанный специально для отказа от управления. View с дочерними представлениями (subviews) должен был опрашивать контроллеры этих представлений. Как только Controller получал управление, он запрашивал результаты ввода с клавиатуры или от мыши и посылал сообщения в View или Model (по обстоятельствам), например о перемещении мыши, щелчке кнопки и т. д. В терминологии MVVM это сравнимо с подпиской на события элемента управления либо в отделенном коде View, либо через команду ViewModel. Когда пользователь взаимодействует с этим элементом управления, вызывается соответствующий метод.

WPF-разработчикам в отличие от разработчиков на Smalltalk MVC не требуется запрашивать буферы клавиатуры, а также упаковывать и генерировать события.

К этому моменту вы начинаете улавливать смысл Controller в контексте MVC и среды, которая не обрабатывает события автоматически за вас. WPF-разработчикам в отличие от разработчиков на Smalltalk MVC не требуется запрашивать буферы клавиатуры, а также упаковывать и генерировать события. Вы просто подписываетесь на них, и подходящий метод «автомагически» принимает их через Microsoft Event Pattern. Зная это, следующее, возможно, будет иметь другой, менее запутанный смысл.

В статье Стива Бербека (Steve Burbeck) «Applications Programming in Smalltalk-80: How to Use Model-View-Controller (MVC)» (bit.ly/3ZfFCX) говорится:

«Контроллер интерпретирует пользовательский ввод через клавиатуру и мышь, командуя модели и/или представлению внести соответствующие изменения. Наконец, модель управляет поведением и данными предметной области приложения, реагирует на запросы информации о своем состоянии (обычно от представления) и на указания изменить состояние (обычно от контроллера)».

Иллюстрацию этой концепции см. на рис. 2.

Рис. 2. Smalltalk Model-View-Controller

Чтобы внести окончательную ясность в весьма запутанную тему, заглянем в документ «Twisting the Triad, the Evolution of the Dolphin Smalltalk MVP Application Framework» за авторством Энди Бауэра (Andy Bower) и Блэра Макглашена (Blair McGlashan), который можно скачать по ссылке bit.ly/o8tDTQ в формате PDF. Это один из самых исчерпывающих документов, которые я прочитал по данной тематике. Авторы отмечают следующее касательно Controller: «Представления, конечно, отвечают за отображение данных предметной области, тогда как контроллеры обрабатывают исходные жесты пользователя».

Я привел это высказывание, чтобы прояснить другое определение. Для полного понимания этой статьи (и других статей на тему MVC) вы должны разобраться в том, что означает термин «жесты» («gestures») (рис. 1). В своем исследовании я наткнулся на статью «An Introduction to GUI Programming with UIL and Motif» (bit.ly/pkzmgc), где утверждается следующее:

«Суть этих этапов в том, что Motif-программа ничего не делает, пока пользователь не запросит некую операцию. Операции запрашиваются выбором команды из меню, щелчком кнопки или другого окна либо нажатием клавиши. Это и есть в собирательном смысле пользовательские жесты. Каждый жест инициирует вызов функции приложения для выполнения неких задач».

Энди Бауэр, соавтор «Twisting the Triad», поделился со мной своими мыслями по поводу «жестов»:

«Мой подход к “жестам” заключается в том, что они являются объединением одного или более пользовательских событий в нечто более осмысленное.

Например, TextController мог бы поглощать события нажатия и отпускания клавиши и преобразовывать их в индивидуальные жесты “касания клавиши”. Аналогично SelectionInListController (Controller, подключенный к окну списка) мог бы абсорбировать несколько событий нажатия и отпускания кнопки, а также отслеживания перемещения мыши в границах списка и интерпретировать их как единый жест “выбора в списке”.

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

Суммируя логику Controller, можно увидеть, что функция контроллера довольно единообразна в различных вариациях MVC, о которых упоминалось в этой статье. Поскольку элементы управления от Microsoft (виджеты) сами интерпретируют пользовательский ввод с клавиатуры и от мыши, вы просто подписываетесь на события и указываете метод, который должен выполняться при определенном событии, — «Controller» внутри ваших элементов управления запускает этот метод за вас (обрабатывая его на уровне ОС). Поэтому у вас нет нужды в контроллере как таковом, что четко изложено в статье «Twisting the Triad». Без Controller вы останетесь в Windows-приложениях с шаблоном Model-View. Всегда помните об этом, изучая MVC и его прикладную и презентационную модели, потому что без Controller не было бы и триады (рис. 3).

Рис. 3. Без Controller это был бы шаблон Model-View (а не Model-View-Controller)

Стоит упомянуть, что неоднозначность MVC была вызвана не только контроллером. В случае Smalltalk MVC бизнес-логика и логика предметной области находится в Model, а в случае VisualWorks MVC прикладная логика, необходимая для отображения пользователю одного или более бизнес-объектов (либо объектов предметной области), размещается в ApplicationModel (рис. 4). Более подробно это освещается в статье «Twisting the Triad». Если подумать, то Application Model и Presentation Model имеют одинаковую функциональность с одним четким различием: Presentation Model не может обращаться к View (Мартин Фаулер провел такое различие, чтобы не перегружать термины). В этом случае WPF-разработчики могут быстро понять смысл Presentation Model, так как фактически это MVVM. Джон Госсмен (John Gossman), отец-основатель MVVM, объясняет это в статье «PresentationModel and WPF» в своем блоге по ссылке bit.ly/pFs6cV. Как и Мартин Фаулер, он тщательно избегал перегруженности терминов. В итоге мы получаем четкое понимание того, что такое MVVM: это «WPF-специфичная версия шаблона PresentationModel».

Рис. 4. VisualWorks Model-View-Controller

Увидев MVC в правильном свете, вы поймете истинные роли Model и View. Это фактически единственные два места для размещения бизнес-логики и/или логики предметной области. Прочитав «Twisting the Triad», становится ясным, что обязанности Application Model были переданы Presenter и что нельзя просто заменить Controller на Presenter — это не синонимы.

Шаблон MVP

Детальное рассмотрение, которого заслуживает MVP, выходит за рамки этой статьи; к счастью, есть много документов, где он подробно обсуждается, например «Twisting the Triad» и «Potel Paper» (можно скачать по ссылке bit.ly/dF4gNn в формате PDF).

Однако я отмечу, что в статье «Twisting the Triad» есть важное утверждение, в котором проясняются причины эволюции MVC в MVP:

«Другая раздражающая особенность MVC, по крайней мере в отношении Dolphin, заключалась в том, что сама идея контроллера не слишком изящно укладывалась в концепцию Windows-среды. Microsoft Windows, как и большинство современных графических операционных систем, предоставляет набор встроенных виджетов, из которых можно конструировать пользовательские интерфейсы. Эти “окна” уже включают многое из функциональности контроллера, являющейся частью нижележащей операционной системы».

Я также хотел бы выделить одну фразу из статьи Мартина Фаулера «GUI Architectures»: «Необходимость прямого манипулирования виджетами многие считали не слишком изящным обходным вариантом, и жто способствовало разработке шаблона Model-View-Presenter». Это важно понимать, так как MVVM глубоко укоренила Presentation Model в умы многих WPF-разработчиков; они считают прямое обновление View плохим стилем программирования. Это верно для MVVM и Presentation Model, потому что, как только вы ссылаетесь на View, вы больше не можете повторно использовать ViewModel с другим View (основная причина появления такого правила). Данный лимитирующий фактор был одной из причин, по которой Smalltalk MVC эволюционировал в шаблон MVP. В случае MVPVM разработчики могут напрямую обращаться к View и ViewModel, что позволяет обеспечить полное отделение View и ViewModel (рис. 5). Представления могут повторно использовать другие ViewModel, а ViewModel — другие представления (вы убедитесь в этом позднее, когда мы перейдем к рассмотрению шаблона MVPVM); это одно из многих крупных преимуществ MVPVM.

Увидев MVC в правильном свете, вы поймете истинные роли Model и View.

Рис. 5. Model-View-Presenter с управлением контроллером

Энди Бауэр поделился со мной следующей информацией по этой тематике, чтобы еще больше прояснить суть вопроса:

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

Однако в конечном счете у Model есть два интерфейса, которые должны быть совместимы с любыми сопоставленными View и Presenter. Первый — стандартный интерфейс вызова функций, применяемый для получения/задания значений и выполнения команд. Второй — интерфейс событий, который должен быть таким, каким его ожидает View (шаблон Observer). Эту комбинацию интерфейсов можно называть протоколом.

Например, в Dolphin MVP виджету “список” (триаде) нужны три компонента с совместимыми протоколами: ListModel, ListView и ListPresenter».

Как только вы понимаете, почему нельзя напрямую обновлять View, — и осознаете, что именно это послужило одной из причин появления нового проектировочного шаблона, который обеспечивает эффективное повторное использование объектов, снимая запрет на обновление View, — вы сразу же получаете возможность задействовать новые средства. Вы живете в Agile-мире и должны менять шаблоны не только своего кода, но и своего мышления, чтобы не вернуться «в круги своя».

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

Шаблон MVPVM

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

Следующие определения компонентов MVPVM заимствованы из «Twisting the Triad» (где это применимо); я счел эти сведения информативными и точными, поэтому, стремясь предоставить вам самую качественную информацию, я просто процитирую определения из той статьи. Эти определения верны для MVPVM (рис. 6) и сегодня — так же, как и для MVP в марте 2000 года, когда была написана «Twisting the Triad».

Рис. 6. Model-View-Presenter-ViewModel


(Примечание: в данной статье рассматривается Prism, но MVPVM будет работать и без Prism; в этом случае различные компоненты будут жестко связаны со своими реализациями вместо разрешения с помощью контейнера встраивания зависимостей Unity или Managed Extensibility Framework [MEF].)

MVPVM: Model

«Это данные, с которыми будет оперировать пользовательский интерфейс. Обычно это объекты предметной области, и цель в том, чтобы такие объекты ничего не знали о пользовательском интерфейсе».

Отделение Model от ViewModel необходимо для встраивания зависимостей (dependency injection) и его применения на уровнях BLL и DAL для поддержки CRUDL-операций (Create, Read, Update, Delete, List) над сохраняемыми данными. В MVPVM только DAL имеет доступ к сохраняемым объектам в Model.

MVPVM: View

«Поведение представления в MVP во многом похоже на таковое в MVC. Представление отвечает за отображение содержимого модели. От модели ожидается инициация соответствующих уведомлений об изменениях при каждом изменении данных, и это позволяет представлению “отделяться” от модели, следуя стандартному шаблону Observer. Так же, как в MVC, это дает возможность подключать несколько представлений к одной модели».

(Примечание. Я использовал цитату выше, чтобы подчеркнуть, что MVP не является новым шаблоном и что сегодня он работает так же, как и в те дни, когда был разработан на основе MVC. Однако в цитате упоминается модель, тогда как MVPVM использует ViewModel.)

В случае MVPVM нужды в отделенном коде никогда не было. Presenter (презентатор) имеет доступ к View и может подписываться на события, манипулировать элементами управления и UI. Это дает проверенные преимущества при разработке приложений, ориентированных на несколько платформ. User ListBox не поддерживает связывания с данными для события изменения выбора, поэтому мне пришлось придумать способ, который работал бы на всех трех платформах (потому что они используют одинаковый код). При активации View я вызываю WireUpUserListBox (см. рис. 7, строку 174) и использую View для получения ссылки на свой элемент управления lstUserList (который находится в DataTemplate). Получив ссылку, я подключаю его к событию SelectionChanged и обновляю свойство ViewModel SelectedUser. Такой вариант работает в настольной ОС, Silverlight и Windows Phone.

Рис. 7. Преимущества возможности прямого обращения к View

View ничего не знает о ViewModel, поэтому они не являются жестко связанными. Если ViewModel поддерживает все свойства, с которыми связывается View, он может легко использовать View. Presenter отвечает за подключение представлений к их ViewModel, настраивая DataContext на соответствующий ViewModel.

MVPVM: Presenter

«Хотя за отображение данных модели отвечает представление, управление тем, как модель может манипулировать пользовательским интерфейсом и изменять его, возлагается на презентатор. Именно в нем размещается логика поведения приложения. Во многих отношениях презентатор MVP является эквивалентом прикладной модели в MVC; большая часть кода, имеющая дело с тем, как работает пользовательский интерфейс, встроена в класс презентатора. Основное отличие в том, что презентатор напрямую связывается с соответствующим представлением, чтобы они оба могли тесно взаимодействовать в управлении пользовательским интерфейсом для конкретной модели».

В Presenter будут все зависимости от интерфейсов для BLL, из которых ему нужно получать объекты предметной области (данные), как показано в левой секции окна на рис. 8. Он будет использовать разрешенные экземпляры так, как сконфигурировано в модуле (см. рис. 8, нижнюю секцию справа) или начальный загрузчик (bootstrapper) для доступа к данным и заполнения ViewModel.

Рис. 8. Код модуля Security

Обычно только Presenter жестко связывается с некоторыми компонентами в MVPVM: View, ViewModel и интерфейсами BLL. Презентаторы не предназначены для повторного использования — они ориентированы на решение конкретных задач, а также поддержку бизнес-логики и правил для этих задач. В тех случаях, где какой-либо Presenter может быть повторно использован в других корпоративных приложениях, скорее всего для определенной задачи лучше подойдет модуль, т. е. вы могли бы, например, создать модуль для входа (проект), который можно было бы повторно использовать во всех ваших корпоративных приложениях. Если вы пишете код применительно к некоему интерфейсу, этот модуль можно легко использовать повторно, применяя технологии встраивания зависимостей, такие как MEF или Unity.

MVPVM: ViewModel

«В MVP модель является просто объектом предметной области, и предполагается, что она вообще не будет связана ни с каким пользовательским интерфейсом».

Это предотвращает жесткое связывание ViewModel с одним View, позволяя повторно использовать его с несколькими View. Аналогично в ViewModel нет бизнес-логики приложения, поэтому ViewModel можно легко разделять между корпоративными приложениями. Это способствует повторному использованию и интеграции приложений. Для примера посмотрите на рис. 8, на верхнюю справа секцию, строку 28. Этот SecurityCommandViewModel находится в проекте Gwn.Library.MvpVm.xxxx (где xxxx = Silverlight, настольная ОС или Windows Phone). Поскольку User ViewModel требуется в большинстве приложений, он является повторно используемым компонентом. Нужно соблюдать осторожность, чтобы не «загрязнить» его бизнес-логикой, специфичной для демо-приложения. Это не проблема в MVPVM, так как бизнес-логика будет обрабатываться Presenter, а не в ViewModel (рис. 6).

В случае MVPVM только в DAL хранится специфическая информация, необходимая для извлечения данных.

(Примечание. Так как свойства ViewModel заполняются Presenter, они будут генерироваться события NotifyPropertyChanged, оповещающие View о наличии новых данных, и View сам отвечает за свое обновление данными ViewModel при получении такого уведомления.)

Уровень бизнес-логики

Уровни бизнес-логики (BLL) ничего не знают о хранящихся в Model данных. Они работают строго с объектами предметной области и интерфейсами. Обычно вы будете использовать встраивание зависимостей для разрешения своего DAL-интерфейса в BLL, поэтому впоследствии сможете заменять DAL, не влияя на любой нижележащий код. Обратите внимание на рис. 9 (строка 34), что в своем демо-приложении я использую реализацию MockBll для IBusinessLogicLayer. Позже я смогу легко заменить ее производственной реализацией этого интерфейса одной строкой кода, так как я вел разработку с использованием этого интерфейса.

Рис. 9. Регистрация BLL, DAL и команд

Бизнес-логика не ограничена BLL. На рис. 9 я регистрирую именованные типы (для IPresenterCommand), чтобы можно было использовать встраивание зависимостей в виде фабрики. Когда пользователь щелкает кнопку (строки 29–33 на рис. 10), базовый класс разрешает (создает экземпляр) параметр команды, и выполняется соответствующая команда. Например, LoginCommand (рис. 8, верхняя справа секция) — это команда, которая будет активировать UserManagerView. Для подключения этого понадобилась лишь команда Button в XAML и элемент в SecurityModule (рис. 8, нижняя справа секция, строка 32).

Рис. 10. DataTemplate для UserCommandViewModel

Уровень доступа к данным

Постоянные данные предметной области могли бы храниться в базах данных SQL, в XML- или текстовых файлах, либо извлекаться из REST-сервиса. В случае MVPVM только в DAL хранится специфическая информация, необходимая для извлечения данных. DAL будет возвращаться в BLL только объекты предметной области. Это избавляет BLL от необходимости знать строки подключения, описатели файлов, REST-сервисы и др. Тем самым увеличивается масштабируемость и расширяемость; вы можете легко переключать свой DAL с XML-файла на облачный сервис, не затрагивая существующий код вне DAL и конфигурационный файл приложения. Если модульные тесты вашего нового DAL работают в CRUDL-процессах, вы можете конфигурировать приложение на использование нового DAL, не влияя на текущие приложения и способы их использования.

Почему важно знать и понимать историю

Благодаря группе Patterns & Practices я смог добиться успеха в работе со своими клиентами, используя передовые технологии и шаблоны вроде MVPVM. Я обнаружил, что шагать в ногу с новыми технологиями и шаблонами этой группы гораздо легче, используя прошлый опыт.

MVP — один из самых продуманных шаблонов. Чтобы в полной мере оценить MVP, вы должны понимать историю развития шаблонов, особенно компонентов MVC. Это не так просто из-за множества факторов, которые мы обсудили в этой статье.

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

Билл Кратохвил (Bill Kratochvil) — независимый подрядчик, главный технолог и архитектор в элитной группе разработчиков, работающей над конфиденциальным проектом для ведущей компании в медицинской промышленности. Его собственная компания, Global Webnet LLC, расположена в Амарилло, штат Техас.

Выражаю благодарность за рецензирование статьи экспертам Энди Бауэру (Andy Bower), Кристине Хелтон (Christina Helton) и Стиву Сандерсону (Steve Sanderson).

MVC — что это, концепция и главная ошибка использования

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

MVC расшифровывается как Model-view-controller, а дословно перевести можно как Модель-Представление-Контроллер.

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

Концепция MVC или из чего она состоит

Модель MVC включает в себя три компонента: Модель, Представление и Контроллер.

Самое главное конечно здесь первое – это Модель. Модель представляет собой совокупность процедур и алгоритмов обработки данных. Сама по себе Модель не содержит данных, но как правило черпает их из базы данных и обрабатывает по заранее прописанным алгоритмам. Если говорить о Web разработке, то модель будет содержать набор классов и функций, например на языке PHP.

Второй элемент – это представление View. Позволяет отобразить информацию. Если это сайт, то информация отображается в браузере. Представление при разработке сайтов содержит HTML код, в который подставляются переменные, которые берутся, нет не из модели, а из контроллера.

Итак, третий элемент – это Контроллер. Его главная функция это обеспечение связи в пользователем и моделью. Также может содержать PHP код.

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

Для примера рассмотрим модель MVC для новостного сайта

Пользователь попадает на страницу сайта. Ему отображается страница по умолчанию с определенным списком новостей. Информация для формирования новостей берется из базы данных.

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

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

Представление, получив массив или объект с новостями подгружает определенный код HTML, CSS, если нужно и jаvascriptи отображает все это пользователю.

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

Таким образом, используя модель MVC можно без проблем составить систему администрирования для сайта, Интернет-приложение. Так фреймфорк CodeIgniter использует именно эту модель.

Программа Model-View-Controller MVC — что это, особенности и описание

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

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

Основные типы функциональности архитектуры

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

  1. Код модели обычно отражает реальные вещи. Этот код может содержать необработанные данные или определять основные компоненты приложения. Например, если пользователь создавал приложение Todo, код модели определял бы, что такое «задача» и что такое «список», поскольку это основные компоненты данного приложения.
  2. Вид, или представление — просмотр кода состоит из всех функций, которые непосредственно взаимодействуют с пользователем. Это код, который делает приложение красивым и в противном случае определяет, как пользователь видит и взаимодействует с ним.
  3. Контроллер действует как связь между моделью и представлением, принимая пользовательский ввод и решая, что с ним делать. Это мозг приложения и связывает модель и представление. Контроллер считают «средним уровнем». Он взаимодействует с пользователем, собирая данные, контактирует с моделью, получая необходимые данные, а затем с представлением, чтобы ответить пользователю.


Когда пользователь выполняет какое-либо действие, он сначала переходит к контроллеру. Он будет принимать любые данные, например, $_GET, $_POST переменные в PHP, и определять, что делать с этими данными. Короче говоря, модели относятся к обработке данных и расширенной функциональности. Поэтому задача контроллера в этой точке состоит в том, чтобы определить, какую модель следует вызывать, а затем открыть соответствующую функцию внутри этой модели. После вызова функции он будет находить результат, обычно в переменной среде.

Модель – это простое представление о том, что пользователь выполняет в приложении. Модель MVC — это что должны представить в коде, например книги пользователя, его банковского счета или чего-то еще. Модель отвечает за хранение функций и переменных, которые связаны с тем, что она представляет.

Можно думать о логике модели как о базовой концепции объектно-ориентированного программирования. Тут модели — это просто «классы». Не стоит путать с классами в контроллерах, которые технически тоже структурированы как классы. Наконец, после того как контроллер запрашивает информацию из модели, она отправляет ее в представление.

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

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

Структура организации кода

Большая идея MVC заключается в том, что каждая часть кода имеет свою цель, и эти цели различны. Некоторые из кодов содержат данные приложения, некоторые делают приложение приятным, а некоторые из них контролируют функциональность.

Считается, что это MVC, программа, которая способна организовать основные функции кода в свои, аккуратно организованные ящики. Структура файла для использования MVC стандартным образом довольно проста — есть просто папки для представлений, моделей и контроллеров, и все они связаны друг с другом через один каталог. Конечно, с любым веб-приложением у пользователя также будут другие папки и файлы, такие как индексный файл и папка для изображений.

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

Структура ASP.NET Core MVC — это легкая среда представления. Отличается открытым исходным кодом. Она высоко проверяемая, оптимизированная для использования с Asp Net Core MVC.

Архитектура MVC

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

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

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

Аналогия модели в современном мире

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

Модель в приложении ToDo может определить что «задача» есть и что «список» представляет собой набор задач. Код View определит, как выглядят ToDo и списки визуально. Задачи могут иметь большой шрифт или быть определенного цвета. Наконец, контроллер может определить, как пользователь добавляет задание или отмечает, когда оно завершено. Контроллер соединяет кнопку «Добавить» в «Модель» поэтому, когда пользователь нажимает «Добавить задачу», модель добавляет новую задачу.

Просто о шаблоне проектирования

Возможности MVC приложения можно показать в двух словах, на примере адресной книги. Модель представляет собой список Person объектов. Представление представляет собой окно графического интерфейса пользователя, которое отображает список людей. А контроллер обрабатывает такие действия, как «Удалить адрес человека», «Добавить адрес человека», «Электронная почта человека».

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

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

Основные зависимости элементов

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

В настоящее время существует три класса:

  1. Person.
  2. PersonListController.
  3. PersonListView.

Необходимо создать два класса: PersonPhotoGridView и PersonPhotoGridController. Person класс остается тем же самым и легко вставляется в две различные точки зрения. Разработчик должен модифицировать Person класс для размещения нового PersonPhotoGridView и в конечном итоге усложняет модель (пример 3).

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

В setPicture этот момент метода является в основном кодом спагетти. Шаблон проектирования MVC вставляет класс контроллера между представлением и моделью, чтобы удалить зависимости модели. При удалении зависимостей модель и, возможно, вид могут быть сделаны повторно используемыми без изменений. Это делает внедрение новых функций и техническое обслуживание легкими. Пользователи быстро получают стабильное программное обеспечение, компания экономит деньги, а разработчики работают в нормальных условиях.

Принцип работы

Принцип MVC состоит в том, чтобы разделить приложение на 3 основные части, известные как Модель, Вид (просмотр) и Контроллер. Видимыми на диаграмме являются прямые ассоциации (красные стрелки) и выведенные ассоциации (голубые стрелки). Выведенные ассоциации — это те, которые могут казаться очевидными с точки зрения пользователя, а не исходя из фактического дизайна программного обеспечения.

Простой способ выполнения условия:

  1. Пользователь взаимодействует с представлением — нажатием на ссылку или отправкой формы.
  2. Контроллер обрабатывает ввод пользователя и передает информацию в модель.
  3. Модель получает информацию и обновляет ее состояние, добавляет данные в базу данных, например, вычисляет сегодняшнюю дату.
  4. Просмотр проверяет состояние Модели и отвечает соответственно, перечислив недавно введенные данные.
  5. Вид ожидает следующего взаимодействия пользователя.

Это простая концепция — Business Logic — вычисления логических процессов приложения. Например, бизнес-логика простого календаря должна была бы рассчитать, какая дата, какой день недели и какой день месяца, если нужно представить все дни в этом месяце. Или осуществлять обслуживание веб-контента с помощью Spring MVC, которая дает возможность строить приложение со статической домашней страницей, принимающей запросы HTTP GET.

Соблюдение принципа DRY

Многие фреймворки MVC используют систему шаблонов для обеспечения соблюдения принципа DRY, что делает его очень удобным для повторного использования кода без необходимости переписывания. Существуют рамки MVC, которые работают на Smarty или используют собственные механизмы шаблонов. Простым предупреждением является то, что некоторые движки шаблонов имеют довольно сложный синтаксис – программисту требуется проверить их, прежде чем начинать разработку.

Считается, что MVC – это еще одна очень хорошая реализация философии DRY (Do not Repeat Yourself). По сути, DRY используется Ruby on Rails и несколькими другими реализациями, а идея состоит в том, что программист пишет что-то один раз и один раз использует код. Принцип DRY определяется как «каждая часть должна иметь единое, однозначное, авторитетное представление внутри системы». Правильная реализация DRY означает, что изменение одного элемента системы не изменяет несвязанные элементы, что довольно логично.

Конвенция по конфигурации

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

Также можно установить все методы формы в POST, если не указано иное. Применение этой идеи ко всем элементам делает создание такого типа приложения очень быстрым, простым и понятным. MVC — это действительно хороший способ начать производство чистого, масштабируемого, мощного и быстрого кода за меньшее время с минимальными затратами усилий. Некоторые структуры MVC не содержат всех этих функций, большинство из них содержат только один или два.

Преимущества и недостатки метода

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

  1. Быстрый процесс разработки, поддерживает быстрое и параллельное развитие.
  2. С MVC один программист может работать над представлением, а другой может работать над контроллером для создания бизнес-логики.
  3. Приложение, разработанное с его применением, в три раза быстрее, чем приложение, разработанное с другими шаблонами разработки.
  4. Возможность предоставления нескольких видов.
  5. В MVC можно создавать несколько представлений.
  6. Копирование дубликатов очень ограничено, поскольку оно отделяет данные и логику от дисплея.
  7. Поддержка асинхронной технологии, которая помогает разработчикам разрабатывать быстро загружаемое приложение.
  8. Модификация не влияет на всю модель, потому что часть модели не зависит от части просмотров. Поэтому любые изменения в Модели не будут влиять на всю архитектуру.
  9. Шаблон NET MVC возвращает данные без применения какого-либо форматирования, поэтому одни и те же компоненты могут использоваться и вызываться для использования с любым интерфейсом.
  10. С помощью этой платформы очень легко разрабатывать URL-адреса, оптимизированные для SEO, для получения большего количества посещений из определенного приложения.
  1. Повышенная сложность.
  2. Неэффективность доступа к данным.
  3. Сложность использования MVC с современным пользовательским интерфейсом.
  4. Нужно несколько программистов.
  5. Требуется знание нескольких технологий. Разработчик знает код клиентской стороны и html-код.

Создание первого приложения

Можно разработать примеры ASP.NET MVC с соответствующей версией среды Visual Studio и .NET, используя MVC v5.2, 2020 Community и платформу .NET 4.6.

  1. Открыть программу Visual Studio 2020 и далее: Файл -> Создать > Проект.
  2. Разворачивают узел Visual C # и Web в левой части и далее выбирают asp net MVC в средней части.
  3. Вводят название своего проекта MyMVCApplication, можно указать любое подходящее имя для своего приложения.
  4. Устанавливают местоположение проекта, нажав «Обзор» и далее «ОК».
  5. В окне «Новое веб-приложение» находят asp MVC core.
  6. Изменяют аутентификацию, нажав соответствующую кнопку.
  7. Нажимают «ОК», чтобы MVC создал проект с использованием шаблона.
  8. Первое приложение готово.

Запускают проект в режиме отладки F5 или Ctrl + F5 без отладки.

Проект MVC framework включает JavaScript и файлы CSS bootstrap 3.0 по умолчанию.

Таким образом можно создавать отзывчивые веб-страницы. Этот отзывчивый пользовательский интерфейс изменит его внешний вид на основе размера экрана различных устройств.

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

Таким образом, легко создать свое первое приложение core MVC с помощью Visual Studio 2013.

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

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

Мастер Йода рекомендует:  Искусственный интеллект как и где изучать — отвечают эксперты
Добавить комментарий