Содержание
Принцип MVC в web — программировании
Принцип MVC у веб-программировании (Model — View — Controller, Модель — Представление(Вид) — Контроллер) — одна из наиболее удачных идей на сегодняшний день. Принцип MVC интуитивно понятен на первый взгляд, но не очень простой при углублении. Сначала рассмотрим, для чего он предназначен.
Принцип MVC, позволяет разделить реализацию логики приложения, внешний вид (графический интерфейс, GUI) и взаимодействие с пользователем.
Это приводит к более структурированном коде, позволяет работать над проектом более специализированным людям, упрощает поддержку кода, делает его более логичным и понятным. Изменение в одном из компонентов минимально влияет на остальные. Можно к одной модели подключать разные виды, разные контроллеры.
С другой стороны, это требует большей производительности исполняющих машин, но в последнее время это не есть большой проблемой — все более сложные программистские решения требуют поддержки, и затраты на поддержку намного превысят затраты на более мощное современное оборудование.
Принцип MVC используют практически все современные фреймворки.
Рассмотрим подробнее компоненты.
Model (Модель) — содержит т.н. «бизнес-логику» — обработку и верификацию данных, обращения к базам данных, представляет внутреннее устройство системы. Модель не должна напрямую взаимодействовать с пользователем.
View (Вид, Представление) описывает внешний вид приложения.
Controller (Контроллер) — связующее звено между моделлю и видом, получает данные от пользователя, передает их модели, получает обработанный результат и передает его в представление.
Взаимосвязь можно посмотреть на диаграмме:
Источник изображения: http://www.wikipedia.org
Требования к компонентам:
Модели:
- должны содержать свойства, представляющие конкретные данные;
- должны включать в себя бизнес-логику (например, правила валидации), чтобы убедиться в том, что данные соответствуют предъявленным требованиям;
- могут содержать код для работы с данными.
Представления:
- должны, главным образом, содержать разметку, такую как HTML, и простой PHP код, используемый для обхода, форматирования и отображения данных;
- не должны напрямую обращаться к базе данных. Этим должны заниматься модели;
- не должны напрямую обращаться к
$_GET
,$_POST
и другим переменным, получаемым из запроса пользователя. Эту задачу должен выполнять контроллер. Представления должны использоваться только для оформления данных, полученных от контроллера и модели; - могут напрямую обращаться к свойствам и методам контроллера или моделей. Однако это должно делаться только в целях отображения данных.
Контроллеры:
- могут обращаться к
$_GET
,$_POST
и другим переменным PHP, получаемым из запроса пользователя; - могут создавать экземпляры моделей и управлять ими. К примеру, в типичном действии обновления модели контроллер может сначала создать экземпляр модели, затем заполнить его данными из
$_POST
и, в случае успешного сохранения модели, перенаправить браузер пользователя на страницу созданной модели. Стоит отметить, что само сохранение модели должно быть реализовано в классе модели, а не в контроллере; - не должны содержать SQL-запросы. Их лучше держать в моделях;
- не должны содержать HTML и другую разметку. Её стоит вынести в представления.
(Требования позаимствованы отсюда: http://yiiframework.ru/doc/guide/ru/basics.best-practices)
Кроме концепции MVC существуют и многие другие, например MOVE ( Models, Operations, Views и Events ) — вроде, как эволюция MVC (взято отсюда: http://habrahabr.ru/post/147038/), но эти концепции менее распространенные.
Разделение кода — Основы Веб-программирования
Каналы передачи данных
|
Сетевое программирование
|
Базы данных
|
Основы Веб-программирования
См.также
- Сравнение скорости фреймворков и чистого WSGI
В программном обеспечении принято разделять: программную логику, код, который
относится к данным, настройки и шаблоны. Таким образом, код становится более
структурированным, и его легче развивать, а также сопровождать в дальнейшем.
MVC
См.также
- Статья о фреймворке Ruby on Rails
- Концепция MVC для чайников
MVC (Model-View-Controller: модель-вид-контроллер) — шаблон архитектуры ПО,
который подразумевает разделение программы на 3 слабосвязанных компонента,
каждый из которых отвечает за свою сферу деятельности.
Бешеная популярность данной структуры в Веб-приложениях сложилась благодаря её
включению в две среды разработки, которые стали очень востребованными: Struts и Ruby on Rails. Эти среды разработки наметили пути
развития для сотен рабочих сред, созданных позже.
Паттерн MVC (Model-View-Controller)
- Model — модель, предоставляющая доступ к данным. Позволяет извлекать данные и менять их
состояние; - View — представление, отображающее данные клиенту. В веб-программировании
существует в виде конечных данных (HTML, JSON, …), которые получает
клиент. Может формироваться при помощи генераторов по заданному шаблону,
например Jinja2, Mako; или систем для построения интерфейсов по разметке,
таких, как Windows Presentation Foundation (WPF), либо Qt Widgets; или
описываться декларативно, как это делается в QML и ReactJs. - Controller — контроллер, отслеживающий различные события (действия пользователя) и по
заданной логике оповещающий модель о необходимости изменить состояние системы.
Классические MVC фреймворки:
- Ruby on Rails
- Pylons
MTV
Фреймворк Django ввел новую терминологию MTV.
Примечание
https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names
В Django функции, отвечающие за обработку логики, соответствуют части
Controller из MVC, но называются View, а отображение соответствует части
View из MVC, но называется Template. Получилось, что:
- M -> M Модели остались неизменными
- V -> T Представление назвали Templates
- C -> V Контроллеры назвали Views
Так появилась аббревиатура MTV.
TADA!! Django invented MTV
Вся логика при таком подходе вынесена во View, а то, как будут отображаться
данные в Template. Из-за ограничений HTTP протокола, View в Django
описывает, какие данные будут представленны по запросу на определенный URL.
View, как и протокол HTTP, не хранит состояний и по факту является обычной
функцией обратного вызова, которая запускается вновь при каждом запросе
по URL. Шаблоны (Templates), в свою очередь, описывают, как данные
представить пользователю.
Паттерн MTV (Model-Template-View)
MTV фреймворки:
- Django
RV
См. также
- RV Pyramid
- Что не так в терминологии MVC
- Pyramid wikipedia
В защиту своего дизайна авторы Pyramid написали довольно большой документ,
который призван развеять мифы о фреймворке. Например, на критику модели MVC в
Pyramid следует подробное объяснение, что MVC «притянут за уши» к
веб-приложениям. Следующая цитата хорошо характеризует подход к терминологии в
Pyramid:
«Мы считаем, что есть только две вещи: ресурсы (Resource) и виды
(View). Дерево ресурсов представляет структуру сайта, а вид представляет
ресурс.«Шаблоны» (Template) в реальности лишь деталь реализации
некоторого вида: строго говоря, они не обязательны, и вид может вернуть
ответ (Response) и без них.Нет никакого «контроллера» (Controller): его просто не существует.
«Модель» (Model) же либо представлена деревом ресурсов, либо «доменной
моделью» (domain model) (например, моделью SQLAlchemy), которая
вообще не является частью каркаса.Нам кажется, что наша терминология более разумна при существующих
ограничениях веб-технологий.»
Паттерн RV (Resources-View)
Веб ограничен URL, который и представляет из себя дерево ресурсов или
структуру сайта.
Также протокол HTTP не позволяет хранить состояние и
отправлять/принимать оповещения клиенту от сервера, что ограничивает
возможность отслеживания действий клиента для последующего уведомления модели
на изменение состояния.
Поэтому данные часто используются на «frontend»-е
(например в связке React/Redux), а на стороне сервера формируются только один
раз во время ответа, либо загружаются отдельным запросом при помощи AJAX, или
даже с помощью других протоколов, например WebSocket.
RV фреймворки:
- Pyramid
Пример MVC блога
Структура файлов
Приведем структуру нашего блога к следующему виду:
. ├── __init__.py ├── models.py └── views. py 0 directories, 3 files
Примечание
Исходный код доступен по адресу:
- https://github.com/iitwebdev/lectures_wsgi_example/tree/master/1.mvc
Где:
__init__.py
— входная точка программы, которая содержит основные
настройки и запуск Веб-сервераmodels.py
— код, который представляет данные, обычно называется моделиviews.py
— логика программы (в нашем случае WSGI-приложения)
Предупреждение
Примеры работают только в Python3
Данные
models.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ARTICLES = [ { 'id': 1, 'title': 'Lorem ipsum dolor sid amet!', 'content': ''' Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vel tortor eleifend, sollicitudin nisl quis, lacinia augue. Duis quam est, laoreet sit amet justo vitae, viverra egestas sem. Maecenas pellentesque augue in nibh feugiat tincidunt. Nunc magna ante, mollis vitae ultricies eu, consectetur id ante. In ut libero eleifend, blandit ipsum a, ullamcorper nunc. Sed bibendum eget odio eget pellentesque. Curabitur elit felis, pellentesque id feugiat et, tincidunt ut mauris. Integer vitae vehicula nunc. Integer ullamcorper, nunc in volutpat auctor, elit leo convallis nulla, vitae varius mi nisl ac lorem. Sed a lacus mi. In hac habitasse platea dictumst. Cras in posuere velit, id dignissim nisl. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla bibendum suscipit convallis. ''' }, { 'id': 2, 'title': 'Hello', 'content': 'Test2' }, { 'id': 3, 'title': 'World', 'content': 'Test2' }, ] |
Авторизация
Мы использовали самописные WSGI-middleware, которые решают стандартные
задачи. Заменим их на уже существующие:
- selector — URL-диспетчеризация
- wsgi-basic-auth —
авторизация по методу Basic Auth
Настройки авторизации __init__. py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from views import BlogRead, BlogIndex, BlogCreate, BlogDelete, BlogUpdate from wsgi_basic_auth import BasicAuth # third-party import selector def make_wsgi_app(): passwd = { 'admin': '123' } # BasicAuth applications create = BasicAuth(BlogCreate, 'www', passwd) update = BasicAuth(BlogUpdate, 'www', passwd) delete = BasicAuth(BlogDelete, 'www', passwd) # URL dispatching middleware dispatch = selector.Selector() dispatch.add('/', GET=BlogIndex) dispatch.prefix = '/article' dispatch.add('/add', GET=create, POST=create) dispatch.add('/{id:digits}', GET=BlogRead) dispatch.add('/{id:digits}/edit', GET=update, POST=update) dispatch.add('/{id:digits}/delete', GET=delete) return dispatch if __name__ == '__main__': from paste.httpserver import serve app = make_wsgi_app() serve(app, host='0. 0.0.0', port=8000) |
URL-диспетчеризация
Настройки URL-диспетчеризации __init__.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from views import BlogRead, BlogIndex, BlogCreate, BlogDelete, BlogUpdate from wsgi_basic_auth import BasicAuth # third-party import selector def make_wsgi_app(): passwd = { 'admin': '123' } # BasicAuth applications create = BasicAuth(BlogCreate, 'www', passwd) update = BasicAuth(BlogUpdate, 'www', passwd) delete = BasicAuth(BlogDelete, 'www', passwd) # URL dispatching middleware dispatch = selector.Selector() dispatch.add('/', GET=BlogIndex) dispatch.prefix = '/article' dispatch.add('/add', GET=create, POST=create) dispatch.add('/{id:digits}', GET=BlogRead) dispatch.add('/{id:digits}/edit', GET=update, POST=update) dispatch.add('/{id:digits}/delete', GET=delete) return dispatch if __name__ == '__main__': from paste. httpserver import serve app = make_wsgi_app() serve(app, host='0.0.0.0', port=8000) |
WSGI-приложение можно указывать как объект (BlogRead
) или как строку
импорта ("views.BlogIndex"
).
views.py
:
1 2 3 4 5 6 7 8 9 | class BaseArticle(BaseBlog): def __init__(self, *args): super(BaseArticle, self).__init__(*args) article_id = self.environ['wsgiorg.routing_args'][1]['id'] (self.index, self.article) = next(((i, art) for i, art in enumerate(ARTICLES) if art['id'] == int(article_id)), (None, None)) |
urlrelay добавляет результат поиска в переменную с названием wsgiorg.routing_args
.
WSGI-приложения
Практически не изменились.
views.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | from models import ARTICLES class BaseBlog(object): def __init__(self, environ, start_response): self. environ = environ self.start = start_response class BaseArticle(BaseBlog): def __init__(self, *args): super(BaseArticle, self).__init__(*args) article_id = self.environ['wsgiorg.routing_args'][1]['id'] (self.index, self.article) = next(((i, art) for i, art in enumerate(ARTICLES) if art['id'] == int(article_id)), (None, None)) class BlogIndex(BaseBlog): def __iter__(self): self.start('200 OK', [('Content-Type', 'text/html')]) yield b'<h2>Simple Blog</h2>' yield b'<a href="/article/add">Add article</a>' yield b'<br />' yield b'<br />' for article in ARTICLES: yield str.encode( ''' {0} - (<a href="/article/{0}/delete">delete</a> | <a href="/article/{0}/edit">edit</a>) <a href="/article/{0}">{1}</a><br /> '''. format( article['id'], article['title'] ) ) class BlogCreate(BaseBlog): def __iter__(self): if self.environ['REQUEST_METHOD'].upper() == 'POST': from urllib.parse import parse_qs values = parse_qs(self.environ['wsgi.input'].read()) max_id = max([art['id'] for art in ARTICLES]) ARTICLES.append( {'id': max_id+1, 'title': values[b'title'].pop().decode(), 'content': values[b'content'].pop().decode() } ) self.start('302 Found', [('Content-Type', 'text/html'), ('Location', '/')]) return self.start('200 OK', [('Content-Type', 'text/html')]) yield b'<h2><a href="/">Simple Blog</a> -> CREATE</h2>' yield b''' <form action="" method="POST"> Title:<br> <input type="text" name="title"><br> Content:<br> <textarea name="content"></textarea><br><br> <input type="submit" value="Submit"> </form> ''' class BlogRead(BaseArticle): def __iter__(self): if not self. article: self.start('404 Not Found', [('content-type', 'text/plain')]) yield b'not found' return self.start('200 OK', [('Content-Type', 'text/html')]) yield b'<h2><a href="/">Simple Blog</a> -> READ</h2>' yield str.encode( '<h3>{}</h3>'.format(self.article['title']) ) yield str.encode(self.article['content']) class BlogUpdate(BaseArticle): def __iter__(self): if self.environ['REQUEST_METHOD'].upper() == 'POST': from urllib.parse import parse_qs values = parse_qs(self.environ['wsgi.input'].read()) self.article['title'] = values[b'title'].pop().decode() self.article['content'] = values[b'content'].pop().decode() self.start('302 Found', [('Content-Type', 'text/html'), ('Location', '/')]) return self.start('200 OK', [('Content-Type', 'text/html')]) yield b'<h2><a href="/">Simple Blog</a> -> UPDATE</h2>' yield str. encode( ''' <form action="" method="POST"> Title:<br> <input type="text" name="title" value="{0}"><br> Content:<br> <textarea name="content">{1}</textarea><br><br> <input type="submit" value="Submit"> </form> '''.format( self.article['title'], self.article['content'] ) ) class BlogDelete(BaseArticle): def __iter__(self): self.start('302 Found', # '301 Moved Permanently', [('Content-Type', 'text/html'), ('Location', '/')]) ARTICLES.pop(self.index) yield b'' |
Что такое контроллер? | Определение из TechTarget
От
- Айви Вигмор
Контроллер в вычислительном контексте — это аппаратное устройство или программа, которая управляет или направляет поток данных между двумя объектами. В вычислительной технике контроллерами могут быть карты, микросхемы или отдельные аппаратные устройства для управления периферийным устройством. В общем смысле контроллер можно рассматривать как что-то или кого-то, что взаимодействует между двумя системами и управляет обменом данными между ними.
Вот несколько примеров контроллеров:
Графическая карта — это плата с интегральной схемой в компьютере или, в некоторых случаях, монитор, который обеспечивает цифро-аналоговое преобразование, видеопамять и видеоконтроллер, чтобы данные могли быть отправлены на дисплей компьютера.
Игровой контроллер — это устройство ввода для игр.
Плата сетевого интерфейса (NIC) — это компьютерная печатная плата или карта, которая устанавливается в компьютер, чтобы его можно было подключить к сети.
Карта интерфейса WAN (WIC) — это специализированная карта сетевого интерфейса, которая позволяет устройствам подключаться к глобальной сети.
Контроллер флэш-памяти — это часть флэш-памяти, которая взаимодействует с хост-устройством и управляет каталогом файлов флэш-памяти.
Контроллер доставки приложений — это сетевое устройство центра обработки данных, которое помогает управлять клиентскими подключениями к сложным веб-приложениям и корпоративным приложениям.
Контроллер управления основной платой (BMC) — это специализированный служебный процессор, который отслеживает физическое состояние компьютера, сетевого сервера или другого аппаратного устройства с помощью датчиков и связывается с системным администратором через независимое соединение.
Пограничный контроллер сеанса (SBC) — это устройство или приложение, которое управляет тем, как вызовы, также называемые сеансами, инициируются, проводятся и завершаются в сети VoIP (передача голоса по протоколу Интернет).
Основной контроллер домена (PDC) и резервный контроллер домена (BDC) — это роли, которые можно назначать серверу для управления доступом к набору сетевых ресурсов (приложениям, принтерам и т. д.) для группы пользователей.
Последнее обновление: октябрь 2012 г.
узкий AI
Узкий ИИ — это применение технологий искусственного интеллекта для создания высокофункциональной системы, которая воспроизводит — и, возможно, превосходит — человеческий интеллект для определенной цели.
Сеть
-
уровень представленияУровень представления находится на уровне 6 коммуникационной модели взаимодействия открытых систем (OSI) и гарантирует, что …
-
кампусная сетьСеть кампуса — это частная локальная сеть (LAN) или набор взаимосвязанных локальных сетей, обслуживающих корпорацию, государственное учреждение…
-
точка присутствия (POP)Точка присутствия (POP) — это точка или физическое место, где две или более сетей или коммуникационных устройств создают соединение …
Безопасность
-
КровотечениеHeartbleed — уязвимость в некоторых реализациях OpenSSL, криптографической библиотеки с открытым исходным кодом.
-
Что такое управление рисками и почему это важно?Управление рисками — это процесс выявления, оценки и контроля угроз капиталу и доходам организации.
-
Что такое кибербезопасность?Кибербезопасность — это защита подключенных к Интернету систем, таких как оборудование, программное обеспечение и данные, от киберугроз.
ИТ-директор
-
PMO (офис управления проектами)Офис управления проектами (PMO) — это группа, агентство или отдел, который определяет и поддерживает стандарты управления проектами…
-
эмоциональный интеллект (ЭИ)Эмоциональный интеллект (ЭИ) — это область когнитивных способностей, которая способствует межличностному поведению.
-
агент изменений (агент изменений)Агент изменений или агент изменений — это тот, кто продвигает изменения и позволяет им происходить в любой группе или организации.
HRSoftware
-
самообслуживание сотрудников (ESS)Самообслуживание сотрудников (ESS) — это широко используемая технология управления персоналом, которая позволяет сотрудникам выполнять множество связанных с работой …
-
платформа обучения (LXP)Платформа обучения (LXP) — это управляемая искусственным интеллектом платформа взаимного обучения, предоставляемая с использованием программного обеспечения как услуги (…
-
Поиск талантовПривлечение талантов — это стратегический процесс, который работодатели используют для анализа своих долгосрочных потребностей в талантах в контексте бизнеса …
Служба поддержки клиентов
-
распознавание голоса (распознавание говорящего)Распознавание голоса или говорящего — это способность машины или программы принимать и интерпретировать диктовку или понимать и . ..
-
ТАМ САМ СОМTAM SAM SOM — это набор аббревиатур, используемых для количественной оценки деловых возможностей бренда на данном рынке.
-
видеомаркетингВидеомаркетинг — это использование видеоконтента для продвижения бренда, продукта или услуги.
Понимание Model-View-Controller
Как и все остальное в программной инженерии, кажется, что концепция Модель-Представление-Контроллер изначально была изобретена программистами на языке Smalltalk.
В частности, он был изобретен одним программистом Smalltalk, Трюгве Реенскаугом. Trygve поддерживает страницу, которая объясняет историю MVC его собственными словами. Он приходит к этим определениям в статье, опубликованной 10 декабря 1979 года:
- Модели
Модели представляют знания. Моделью может быть один объект (довольно неинтересный) или некоторая структура объектов.
Между моделью и ее частями, с одной стороны, и изображаемым миром в восприятии владельца модели, с другой стороны, должно быть взаимно однозначное соответствие.
- просмотров
Представление — это (визуальное) представление своей модели. Обычно это выделяет одни атрибуты модели и подавляет другие. Таким образом, он действует как фильтр представления.
Представление привязывается к своей модели (или части модели) и получает необходимые для презентации данные от модели, задавая вопросы. Он также может обновлять модель, отправляя соответствующие сообщения. Все эти вопросы и сообщения должны быть в терминологии модели, поэтому представление должно знать семантику атрибутов модели, которую оно представляет.
- Контроллеры
Контроллер является связующим звеном между пользователем и системой. Он предоставляет пользователю входные данные, организуя отображение соответствующих представлений в соответствующих местах на экране. Он предоставляет средства для пользовательского вывода, предоставляя пользователю меню или другие средства предоставления команд и данных. Контроллер получает такой пользовательский вывод, переводит его в соответствующие сообщения и передает эти сообщения одному или нескольким представлениям.
Может показаться, что сейчас мы находимся глубоко на территории архитектурных астронавтов, но потерпите меня. Концепции MVC немного абстрактны, это правда, но это невероятно распространенный шаблон. Это буквально все вокруг вас. На самом деле, позвольте мне вернуть это на Землю следующим образом: вы смотрите на MVC прямо сейчас .
Модель = HTML | Вид = CSS | Контроллер = Браузер |
Эта вездесущая тройка почти идеально представляет MVC.
- Модель
HTML — это «скелет» основного контента. Текст, сообщающий информацию читателю.
- Вид
CSS добавляет визуальный стиль к содержимому. Это «кожа», которую мы используем для придания плоти нашему скелету и придания ему особого вида. Мы можем менять скины с помощью CSS без какого-либо изменения исходного содержимого. Они относительно, но не полностью независимы.
- Контроллер
Браузер отвечает за объединение и рендеринг CSS и HTML в набор окончательных, управляемых пикселей на экране. Он собирает входные данные от пользователя и упорядочивает их в любой код JavaScript, необходимый для функционирования страницы. Но и здесь у нас есть гибкость: мы можем подключить другой браузер и получить сопоставимые результаты. Некоторые браузеры могут отображать его быстрее, с большей точностью или с большим количеством наворотов.
Итак, если вы считаете, что сеть вообще успешна, то большинство признаков, которые я видел, указывают на да — тогда вы также должны признать невероятную мощь Model-View-Controller.
Не случайно многие из самых популярных фреймворков веб-программирования также инкапсулируют принципы MVC: Django, Ruby on Rails, CakePHP, Struts и так далее. Он также официально внедряется в ASP.NET в рамках молодого проекта ASP.NET MVC.
Просто взгляните на структуру проекта в образце проекта ASP.NET MVC :
Это почти говорит само за себя, если вы когда-либо создавали приложение любого типа:
- Модель
Классы, которые используются для хранения и управления состоянием, обычно в какой-либо базе данных.
- Вид
Биты пользовательского интерфейса (в данном случае HTML), необходимые для отображения модели пользователю.
- Контроллер
Мозги приложения. Контроллер решает, что ввел пользователь, как модель должна измениться в результате этого ввода и какое результирующее представление следует использовать.
Он прекрасен в своей простоте, как отмечает Теренс Парр:
Для «MVC» веб-приложения я провожу прямую аналогию с понятием MVC в Smalltalk. Модель — это любая логика, база данных или любые данные. Представление — это просто то, как вы размещаете данные, как они отображаются. Например, если вам нужно подмножество некоторых данных, я считаю, что это ответственность модели. Модель умеет делать подмножество. Вы не должны просить своего графического дизайнера отфильтровать список по возрасту или каким-либо другим критериям.
Контроллер в веб-приложении немного сложнее, потому что он состоит из двух частей. Первая часть — это веб-сервер (например, контейнер сервлетов), который сопоставляет входящие HTTP-запросы URL с конкретным обработчиком для этого запроса. Вторая часть — это сами обработчики, которые на самом деле часто называют «контроллерами». Таким образом, C в веб-приложении MVC включает в себя как «повелителя» веб-сервера, который направляет запросы обработчикам, так и логику самих обработчиков, которые извлекают данные из базы данных и помещают их в шаблон. Этот контроллер также получает запросы HTTP POST и обрабатывает их, иногда обновляя базу данных.
Я рассматриваю веб-сайт как не что иное, как граф с ребрами с POST и GET, который маршрутизирует страницы.
Вот один из быстрых способов проверить, правильно ли ваше приложение разделило себя между ролями модели, представления и контроллера: поддерживает ли ваше приложение скин?
По моему опыту, дизайнеры не понимают ни циклов, ни каких-либо состояний. Они понимают шаблоны с дырками в них. Все понимают слияние почты. И если вы скажете: «Примените жирный шаблон к этому отверстию», они тоже это поймут. Таким образом, разделение модели и представления решает очень важную практическую проблему, заключающуюся в том, как заставить дизайнеров работать с программистами.
Другая проблема заключается в том, что невозможно правильно сделать несколько скинов сайта, если у вас нет надлежащего разделения задач. Если вы занимаетесь генерацией кода или сайтами с разными скинами, нет возможности правильно создать новый скин, просто скопировав и вставив старый скин и изменив его.