Модель–представление–контроллер ( MVC ) — это шаблон проектирования программного обеспечения [1], который обычно используется для разработки пользовательских интерфейсов и разделяет связанную логику программы на три взаимосвязанных элемента. Этими элементами являются:
Традиционно используемый для графических пользовательских интерфейсов (GUI) настольных компьютеров, этот шаблон стал популярен для проектирования веб-приложений . [4] Популярные языки программирования имеют фреймворки MVC, которые облегчают реализацию шаблона.
MVC, одно из основополагающих открытий на раннем этапе разработки графических пользовательских интерфейсов, стало одним из первых подходов к описанию и реализации программных конструкций с точки зрения их обязанностей . [5]
Тригве Реенскауг создал MVC, работая над Smalltalk -79 в качестве приглашенного ученого в исследовательском центре Xerox Palo Alto (PARC) в конце 1970-х годов. [6] [7] [8] : 330 Он хотел создать шаблон, который можно было бы использовать для структурирования любой программы, в которой пользователи взаимодействуют с большим, запутанным набором данных . Первоначально его проект состоял из четырех частей: модель , представление, вещь и редактор. После обсуждения с другими разработчиками Smalltalk он и остальная часть группы остановились на модели, представлении и контроллере. [6]
В их окончательном дизайне модель представляет некоторую часть программы чисто и интуитивно. Вид — это визуальное представление модели, извлекающее данные из модели для отображения пользователю и передающее запросы туда и обратно между пользователем и моделью. Контроллер — это организационная часть пользовательского интерфейса, которая размещает и координирует несколько Видов на экране, и которая получает пользовательский ввод и отправляет соответствующие сообщения своим базовым Видам. Этот дизайн также включает Редактор как специализированный вид контроллера, используемый для изменения определенного вида, и который создается посредством этого вида. [6]
Smalltalk-80 поддерживает версию MVC, которая развилась из этой. [6] Она предоставляет абстрактные view
и controller
классы , а также различные конкретные подклассы каждого из них, которые представляют различные общие виджеты . В этой схеме a View
представляет собой некоторый способ отображения информации пользователю, а a controller
представляет собой некоторый способ взаимодействия пользователя с a view
. A view
также связан с объектом модели, но структура этого объекта остается на усмотрение прикладного программиста . Среда Smalltalk-80 также включает «MVC Inspector», инструмент разработки для просмотра структуры заданной модели, представления и контроллера бок о бок. [9]
В 1988 году статья в The Journal of Object Technology (JOT) двух бывших сотрудников PARC представила MVC как общую « парадигму и методологию программирования» для разработчиков Smalltalk-80. Однако их схема отличалась как от схемы Реенскауга и др., так и от представленной в справочниках Smalltalk-80. Они определили представление как охватывающее любую графическую проблему, при этом контроллер был более абстрактным, как правило, невидимым объектом, который получает пользовательский ввод и взаимодействует с одним или несколькими представлениями и только с одной моделью. [10]
Впоследствии шаблон MVC развивался [11] , что привело к появлению таких вариантов, как иерархическая модель–представление–контроллер (HMVC), модель–представление–адаптер (MVA), модель–представление–презентатор (MVP), модель–представление–модель представления (MVVM) и других, которые адаптировали MVC к различным контекстам.
Использование шаблона MVC в веб-приложениях возросло после введения NeXT WebObjects в 1996 году, который изначально был написан на Objective-C (который во многом заимствовал из Smalltalk) и помог реализовать принципы MVC. Позже шаблон MVC стал популярен среди разработчиков Java, когда WebObjects был портирован на Java . Более поздние фреймворки для Java, такие как Spring (выпущенный в октябре 2002 года), продолжили прочную связь между Java и MVC.
В 2003 году Мартин Фаулер опубликовал «Шаблоны архитектуры корпоративных приложений» , в которых MVC был представлен как шаблон, в котором «контроллер ввода» получает запрос, отправляет соответствующие сообщения объекту модели, принимает ответ от объекта модели и передает ответ соответствующему представлению для отображения. [8] : 56 Это близко к подходу, принятому фреймворком веб-приложений Ruby on Rails (август 2004 года), в котором клиент отправляет запросы на сервер через представление в браузере , эти запросы обрабатываются контроллером на сервере, а контроллер взаимодействует с соответствующими объектами модели. [12] Фреймворк Django (июль 2005 года, для Python ) выдвинул похожую версию шаблона «представление шаблона модели» (MTV), в котором представление извлекает данные из моделей и передает их шаблонам для отображения. [13] И Rails, и Django дебютировали с сильным акцентом на быстрое развертывание, что увеличило популярность MVC за пределами традиционной корпоративной среды, в которой он уже давно популярен.
Центральный компонент шаблона. Это динамическая структура данных приложения , независимая от пользовательского интерфейса. [14] Она напрямую управляет данными, логикой и правилами приложения. В Smalltalk-80 разработка типа модели полностью возлагается на программиста. [15] В WebObjects, Rails и Django тип модели обычно представляет собой таблицу в базе данных приложения . [16] [17] [18] Модель необходима для поддержания организованности и согласованности данных. Она гарантирует, что данные приложения ведут себя в соответствии с определенными правилами и логикой.
Любое представление информации, например, диаграмма , график или таблица. Возможны различные представления одной и той же информации, например, столбчатая диаграмма для руководства и табличное представление для бухгалтеров .
В Smalltalk-80 представление — это просто визуальное представление модели, которое не обрабатывает вводимые пользователем данные. [19] В WebObjects представление представляет собой полный элемент пользовательского интерфейса, такой как меню или кнопка, и получает вводимые пользователем данные. [20] Однако и в Smalltalk-80, и в WebObjects представления должны быть универсальными и компонуемыми . [21] [22]
В Rails и Django роль представления играют HTML- шаблоны, поэтому в их схеме представление определяет пользовательский интерфейс в браузере, а не представляет виджет пользовательского интерфейса напрямую. [23] [24] (В связи с этим Django предпочитает называть этот тип объекта «шаблоном». [25] ) Такой подход уделяет относительно меньше внимания небольшим составным представлениям; типичное представление Rails имеет связь «один к одному» с действием контроллера. [26]
Представления Smalltalk-80 взаимодействуют как с моделью, так и с контроллером, [27] тогда как в WebObjects представление взаимодействует только с контроллером, который затем взаимодействует с моделью. [28] В Rails и Django представление/шаблон используется контроллером/представлением при подготовке ответа клиенту. [29] [30]
Принимает входные данные и преобразует их в команды для модели или представления. [31]
Контроллер Smalltalk-80 обрабатывает события пользовательского ввода, такие как нажатия кнопок или движение мыши. [32] В любой момент времени каждый контроллер имеет одно связанное представление и модель, хотя один объект модели может получать сигналы от многих разных контроллеров. Только один контроллер, «активный» контроллер, получает пользовательский ввод в любой момент времени; объект глобального оконного менеджера отвечает за установку текущего активного контроллера. Если пользовательский ввод вызывает изменение в модели, контроллер подаст сигнал модели об изменении, но затем модель отвечает за сообщение своим представлениям об обновлении. [33]
В WebObjects представления обрабатывают пользовательский ввод, а контроллер выступает посредником между представлениями и моделями. На одно приложение или на одно окно может приходиться только один контроллер. Большая часть логики, специфичной для приложения, находится в контроллере. [34]
В Rails запросы, поступающие в серверное приложение от клиента, отправляются на « маршрутизатор », который сопоставляет запрос с определенным методом определенного контроллера. В рамках этого метода контроллер взаимодействует с данными запроса и любыми соответствующими объектами модели и подготавливает ответ с использованием представления. Традиционно каждое представление имеет связанный контроллер; например, если бы приложение имело представление client
, оно, как правило, также имело бы связанный Clients
контроллер. Однако разработчики могут создавать другие виды контроллеров, если пожелают. [35]
Django называет объект, играющий эту роль, «представлением» вместо контроллера. [30] Представление Django — это функция, которая получает веб-запрос и возвращает веб-ответ. Оно может использовать шаблоны для создания ответа. [36]
Помимо разделения приложения на модель, представление и компонент контроллера, шаблон проектирования MVC определяет взаимодействие между этими тремя компонентами: [37]
Как и другие программные шаблоны, MVC выражает «ядро решения» проблемы, позволяя адаптировать его для каждой системы. [38] Конкретные проекты MVC могут значительно отличаться от традиционного описания, данного здесь. [39]
Как писал Алан Кей в 2003 году, изначальной мотивацией MVC было создание графического интерфейса для любого объекта. [40] Это было подробно описано в книге Ричарда Поусона «Обнаженные объекты» . [40]
Тригве Реенскауг, создатель MVC в PARC, написал, что «MVC был задуман как общее решение проблемы управления пользователями большими и сложными наборами данных». [6]
В своем руководстве Inside Smalltalk 1991 года профессора компьютерных наук Карлтонского университета Уилф Лалонд и Джон Пью описали преимущества MVC в стиле Smalltalk-80 следующим образом:
Хотя изначально MVC был разработан для настольных компьютеров , он был широко принят в качестве дизайна для приложений World Wide Web на основных языках программирования . Было создано несколько веб-фреймворков , которые реализуют этот шаблон. Эти программные фреймворки различаются по своим интерпретациям, в основном по способу разделения обязанностей MVC между клиентом и сервером . [42] Ранние фреймворки MVC использовали подход тонкого клиента , который размещал почти всю логику модели, представления и контроллера на сервере. При таком подходе клиент отправляет запросы гиперссылок или отправки форм контроллеру, а затем получает полную и обновленную веб-страницу (или другой документ) из представления; модель полностью существует на сервере. [42] Более поздние фреймворки позволили компонентам MVC частично выполняться на клиенте, используя Ajax для синхронизации данных.
говорить более глубоко, фреймворк существует для разделения представления информации от взаимодействия с пользователем.
Моделью может быть любой объект без ограничений.
В WebObjects модель устанавливает и поддерживает соответствие между классом корпоративного объекта и данными, хранящимися в реляционной базе данных.
создаст
модель, сопоставленную с таблицей продуктов в базе данных.
Product
каждая модель сопоставляется с одной таблицей базы данных.
Вид отвечает за визуальное представление объекта.
Объекты View представляют собой вещи, видимые в пользовательском интерфейсе (например, окна или кнопки).
[MVC] позволяет использовать представления в качестве частей для сборки в более крупные блоки; новые виды представлений могут быть созданы с использованием существующих представлений в качестве подпредставлений.
Объекты представления, как правило, очень пригодны для повторного использования и, таким образом, обеспечивают согласованность между приложениями.
Action View написаны с использованием встроенного Ruby в тегах, смешанных с HTML.
содержит статические части желаемого вывода HTML, а также некоторый специальный синтаксис, описывающий, как будет вставляться динамический контент.
представления имеют общее имя с соответствующим действием контроллера...
представление явно знает о модели и контроллере.
В качестве посредника между объектами Model и объектами View в приложении выступает объект Controller.
В Rails веб-запросы обрабатываются контроллером действий и представлением действий. Обычно контроллер действий отвечает за взаимодействие с базой данных и выполнение действий CRUD при необходимости. Затем представление действий отвечает за компиляцию ответа.
В Django "представление" описывает, какие данные представлены, но представление обычно делегирует полномочия шаблону, который описывает, как представлены данные.
Контроллер отвечает за взаимодействие между пользователем и моделью/представлением. Он интерпретирует символы клавиатуры вместе с движениями мыши и щелчками.
представления имеют общее имя с соответствующим действием контроллера...