Статьи

MVC и веб-приложения: нефть и вода

Откатить часы на два года назад. Это до AJAX, до Web 2.0, до Rails. Где мы были тогда? Хорошо размышляя , действительно ли MVC была такой хорошей идеей в конце концов . Продолжая оттуда …

Что такое MVC?

Для длинного ответа, лучшее, что я видел (для веб-руководителей), — это анализ Джеффа здесь . Там больше можно найти через Википедию и еще больше на старой C2 вики .

Короткий ответ для веб-приложений (с уклоном PHP), вероятно, — способ организации кода, основанного на следующих идеях;

  • Модель — те функции, которые переносят вызовы в вашу БД
  • View — шаблоны / скрипты, которые выводят HTML
  • Контроллер — материал, который проверяет такие переменные, как $ _GET и $ _POST, и решает, что делать дальше

Важно помнить, что нет абсолютного определения MVC, и есть много серых областей для интерпретации, и еще больше, когда речь идет об использовании его в Интернете. Само по себе это означает, что если вы создаете фреймворк, вам просто нужно вставить туда слова «Модель», «Вид» и «Контроллер», и вы, вероятно, так же «правы», как и все остальные. Некоторое время назад Джон Лим осмелился спросить, не слишком ли дерьмо в MVC? Я подозреваю, что пришел за интуицией опытного программиста. В более позднем обновлении он криво прокомментировал;

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

Почему MVC?

Итак, почему MVC стал общим шаблоном (или, по крайней мере, общим термином) для веб-приложений, имея в виду, что он изначально был разработан для помощи в создании настольных графических интерфейсов?

Насколько я знаю, это впервые проявилось в архитектуре Sun Model 2 где-то в 1999 году (?), А затем превратилось в конкретную (и популярную) реализацию: стойки , около 2000 года. Отсюда, прямо скажем, это, кажется, стало самосохраняющейся мантрой или синдромом технического лемминга. Трудно найти обоснование «почему MVC» против любых заданных альтернатив, кроме как это не Модель 1 (ванильный ASP / PHP будет рассматриваться как Модель 1). Большинство фреймворков, которые я вижу сегодня, рекламируют MVC без указания того, почему они его используют.

И давайте посмотрим правде в глаза: MVC звучит впечатляюще (и пугающе) для людей, не знающих. Что мы делаем, когда видим термин, с которым раньше не сталкивались — ищите и находите много других людей, говорящих «Да, MVC».

Итак, задали ли мы достаточно вопросов или мы просто запрыгнули на коллективный фургон? На самом деле Джефф ясно указывает на фактор MVC в значении MVCв MVC должно быть «что-то» из-за спроса на разработчики стоек.

Для меня есть еще один красный флаг, размахивающий тем, что это классический признак MVC в настольных приложениях, где несколько несвязанных представлений автоматически обновляются при любых изменениях модели (Джефф описывает это как активную модель ). К сожалению, в традиционных (как не в AJAX) веб-приложениях представление соответствует одному ответу веб-страницы на браузер, а в протоколе запроса-ответа, таком как HTTP, у сервера нет места для указания какого-либо другого окна браузера, которое вы открыли что он также нуждается в обновлении: веб-серверы не связываются с вами — вы связываетесь с ними. Отличительный признак MVC не работает в Интернете, если вы не взломали какой-либо механизм обновления на стороне клиента для проверки обновлений. Может ли это быть намеком на то, что разделение MVC не совсем подходит?

Я подозреваю, что если мы достаточно громко спросим «Почему MVC был выбран [вставить шаблон здесь?»? », Ответом будет просто перетасовка ног и случайное« Почему нет? ». Возможно, парни, которые использовали «Модель 2», могли бы быть откровенны: «Нам нужен был шаблон, к которому могло бы относиться наше сообщество разработчиков (AWT / Swing), и MVC было достаточно близко. Это не должно было восприниматься всерьез.

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

альтернативы

ASP.NET и JSF пытались довести программирование на основе событий на стороне сервера до смешанных реакций. Учитывая, что у нас сейчас достаточно миль на часах ASP.NET, у меня сложилось впечатление, что опытные веб- разработчики настороженно относятся к ASP.NET, потому что он «слишком умен» — кривая обучения для освоения значительна, и, возможно, слишком много умных вещей сделано прозрачно в этих веб-элементов управления. ASP.NET, вероятно, более приятен тем, кто пришел из VB6. Вопрос о том, является ли программирование на основе событий на самом деле конкурирующей парадигмой MVC, является спорным, но, вероятно, справедливо будет сказать, что он понижает контроллер до менее значимой части.

Тем временем разработчики Coldfusion по- прежнему ладят с fusebox . ‘Достаточно.

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

Сделать ресурсы первым классом

Одна проблема, которую я имею со структурами и производными, состоит в том, что они продвигают действия как объекты первого класса (в Rails действия — это методы класса, но я бы все еще утверждал «первый класс»).

HTTP имеет только два действия (по крайней мере, которые фактически используются) — GET и POST — получить или обновить его. На этом этапе стоит прочитать, почему API веб-сервера отстают так много? ,

Для меня прямое следствие продвижения действий в качестве первоклассных объектов состоит в том, что мы получаем людей, помещающих глаголы в URL-адреса, такие как «http://example.com/item/1/delete», что, в свою очередь, приводит к таким проблемам и предполагает тесную связь (между клиентом и сервером) и RPC . GET четко помечен как «безопасный / только для чтения», а добавление глагола в URL означает, что что-то должно быть сделано (что может быть, а может и не быть безопасным);

В частности, было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение выполнения действия, отличного от извлечения. Эти методы следует считать «безопасными». Это позволяет пользовательским агентам представлять другие методы, такие как POST, PUT и DELETE, особым образом, чтобы пользователь знал о том, что запрашивается небезопасное действие.

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

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

Итак, давайте сделаем ресурсы первоклассными объектами и сделаем так, чтобы API-интерфейсы отражали это. Это то, что REST пытается сказать нам.

Это может означать просто поиск более разумных способов написания кода, ориентированного на представление , с акцентом на DRY и избеганием спагетти — рассмотрите «article.php» в этом URL .

В качестве альтернативы это может означать, что мы проводим больше времени, работая над такими классами, как;

 Класс Шутка расширяет Ресурс {
     function GET ($ Params) {
         # Вернуть / показать шутку
     }
    
     function POST ($ Params) {
         # Создать или обновить шутку
     }
    
     function DELETE ($ Id) {
         # Удалить шутку
     }
 }

 Шутки класса расширяет ресурсы {
     function GET ($ Condition = array ()) {
         # Вернуться / отобразить список шуток
     }
 }

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

Каждый объект имеет URI

И из вступления Пшеницы здесь ;

Меня спросили, почему это требует нового языка (почему-то никто не заботится о новой среде…). Вот один из моих более многословных ответов:

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

Страшно! Что если мы все действительно лаем не то дерево? Возможно, здесь есть связь с интересом к закрытию .

Дополнительное примечание: можно утверждать, что классы содержимого и объекты в eZ Publish вписываются в приведенное выше описание и сохраняются в БД.

AJAX и формы

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

Так, где это оставило бы сторону сервера? Он проталкивает его как минимум на один уровень, чтобы стать «бэк-эндом» — логическим эквивалентом баз данных в веб-приложениях сегодня. Вы просто хотите, чтобы он обслуживал и принимал обновления ресурсов без сохранения состояния — GET и POST.

Если вы все еще применяете MVC на стороне сервера, вы, вероятно, сохраняете его как можно более простым, предпочитая использовать стратегию, а не фреймворк. У вас все еще есть бизнес-логика на сервере, но управляющая логика (включая выполнение рабочих процессов) перенесена в клиент AJAX. Думаю, серверная сторона стала сервисным уровнем .

Примечание: то, что ActiveGrid, похоже, делает с BPEL , движется в этом направлении, хотя это все еще технология на стороне сервера. В рамках «активного мышления» ActiveGrid скрипты PHP (возможно, справедливо) превращаются в «сервисы», просто прокачивающие текст .

Также есть хороший шанс, что вы больше не генерируете формы на стороне сервера, а делаете это динамически с Javascript на стороне клиента. В противном случае, возможно, вы используете «автономные» страницы форм, которые хорошо отделены от других ваших ресурсов . Форма «Мастер», состоящая из нескольких страниц, больше не требует скрытых полей ввода или иным образом, а живет в памяти браузера как объекты Javascript до тех пор, пока форма не будет заполнена. Если удаление генерации форм со стороны сервера кажется надуманным, рассмотрите прецедентное окно поиска в Firefox (вверху справа) — лично я давно не смотрел форму поиска на домашней странице Googles.

То, что я действительно пытаюсь здесь сказать, это то, что я думаю, что стремление к MVC на стороне сервера — это результат одержимости формами, ограничений Javascript, стремления конкурировать с настольными приложениями и такого метода форм = ”УДАЛИТЬ” никогда не было ( поэтому было необходимо связать это как другое действие через POST-действие). У вас есть кнопка в вашей форме под названием «Добавить в корзину», так что вы явно хотите где-нибудь добавить AddToCartAction . С совершенствованием AJAX мы, вероятно, будем реализовывать наши корзины покупок исключительно на стороне клиента, вернувшись к серверу снова где-то за время «Оформления заказа».

RUD не CRUD

Возможно, еще одно похмелье от попыток вывести настольные ПК в интернет — это CRUD — четыре операции: создание, получение, обновление, удаление. С HTTP у вас есть только три важные операции (одна из которых, DELETE, не используется) — извлечение (GET) и обновление (POST): в частности, нет различия между созданием и обновлением. Это может звучать как тривиальная точка, но здесь есть значение, которое упускается из виду.

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

Между тем HTTP был разработан для доступа к ресурсам, «первичный ключ» определяется по его URL (вместо того, чтобы беспокоиться об идентификаторе вставки ). Если вы думаете «документы», ясно, что нет необходимости проводить различие между созданием и обновлением — создание документа приводит к первой версии. Обновление означает перезапись существующего документа новой версией. Но в обоих случаях клиент размещает одно и то же и ему не нужно знать, существовал ли этот документ или нет.

Между тем, распространенным первым демонстрационным приложением для серверных платформ является пример CRUD. Здесь подразумевается, что фреймворки делают сильный акцент на базе данных, в то время как HTTP в значительной степени игнорируется (редко можно даже увидеть коды состояния HTTP как фундаментальную часть фреймворка).

Отказ от длинных обсуждений файловой системы и базы данных (например, необходимость в виртуальных файловых системах с расширяемыми свойствами) достаточно сказать — рассмотрите, как Dokuwiki хранит вики-страницы 1-к-1 как файлы по сравнению с MediaWiki . Что имеет больше смысла для вас? Возможно, наши сайты слишком сильно загнали в базу данных?

Дело в том, что, учитывая несоответствие между HTTP и CRUD, мы поставили CRUD на первое место, что, в свою очередь, делает действия первоклассными в наших средах. Мы стремимся поддерживать N различных типов действий (глаголов), когда на самом деле мы должны были иметь дело только с тремя — GET, POST и DELETE (последний, возможно, перенаправлен на конкретный метод «класса ресурсов» в соответствии с некоторой структурой / формой). конвенции).

Вернуться в запредельный

Возвращаясь к этому пункту , сегодня кажется, что вместо того, чтобы отказываться от MVC, следует отказаться от Java (или Perl / PHP / Python) в пользу платформы, которая сокращает количество строк кода — «MVC с наименьшим количеством боли, пожалуйста». MVC является синонимом наших требований для лучшей разработки веб-приложений: «Вы хотите лучшие практики? Используйте MVC ».

Но как насчет выделения того, что мы на самом деле хотим, в качестве независимого списка — на мгновение забыть о MVC? От макушки головы (и совсем не всеобъемлющей);

  • Няня: расскажи мне, как организоваться — четкие указатели, где разместить мой код.
  • Просто добавь воды: дай мне мой прототип сейчас !
  • Не заставляй меня думать: я могу делать это даже в самые тупые дни.
  • СУХОЙ : сделать одно и то же изменение 50 раз — это не круто.
  • Анти-паста: помогите мне избежать спагетти
  • Безопасность: никаких неприятных сюрпризов, пожалуйста. Помоги мне сделать это правильно с первого раза.
  • Тестирование: помогите мне защитить себя от себя.
  • [вставьте больше здесь] x N

До сих пор я не придумал ничего, что могло бы быть решено только MVC (а некоторые вообще не имеют никакого отношения к MVC).

Возможно, есть лучший шаблон, подходящий для Интернета? Возможно, «контроллер» в MVC подразумевает акцент на «действиях в первую очередь». Если мы опускаем действия в пользу ресурсов, поддерживающих только GET, POST и DELETE, возможно, контроллер обрабатывает нас автоматически?

Во всяком случае, из-за отсутствия лучшего места, чтобы закончить это, цитата из Регистра на пшеницу;

И после самой первой воскресной презентации один из слушателей заявил, что он нашел новый язык веб-программирования Wheat «таким красивым, что заставил меня плакать!»