Mvc фреймворк что это
(от 27 июля 2012)
При написании нативного веб-приложения легко начать чувствовать себя богом, способным работать просто с библиотекой работы с DOM (такой как jQuery) и горсткой сервисных плагинов. Вскоре возникает проблема в виде груды вложенных возвратных функций jQuery и разбросанных DOM-элементов без всякой структуры вместо приложения.
Короче, мы застреваем в спагетти-коде. К счастью, есть современные JS-фреймворки (библиотеки, задающие, кроме функций, правила организации кода --прим. перев.), помогающие поддерживать структуру и организованность в проекте, облегчающие ремонтопригодность в будущем.
Strongly typed views
Razor views in MVC can be strongly typed based on your model. Controllers can pass a strongly typed model to views enabling your views to have type checking and IntelliSense support.
For example, the following view renders a model of type IEnumerable :
Веб-API
Используйте функции создания ссылок для поддержки гипермедиа. Легко включайте поддержку общего доступа к ресурсам независимо от источника (CORS) для совместного использования веб-API в нескольких веб-приложениях.
Dependency injection
Your app can also use dependency injection in view files, using the @inject directive:
Controller Responsibilities
Controllers are the components that handle user interaction, work with the model, and ultimately select a view to render. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. In the MVC pattern, the controller is the initial entry point, and is responsible for selecting which model types to work with and which view to render (hence its name - it controls how the app responds to a given request).
Controllers shouldn't be overly complicated by too many responsibilities. To keep controller logic from becoming overly complex, push business logic out of the controller and into the domain model.
If you find that your controller actions frequently perform the same kinds of actions, move these common actions into filters.
Области
■ Что такое MVC или, лучше сказать, MV*?
Эти современные библиотеки дают разработчикам простой путь к организации кода, используя вариации паттерна проектирования, известного как MVC (Model-View-Controller). MVC разделяет задачи в приложении на 3 части:
Модель (логика) представляют проблемно-ориентированные знания и данные в приложении. Думайте о них как о типе данных, которые сможете смоделировать, о таких, как Пользователь, Фото, или Замечание. Модели должны информировать о чём-либо при наблюдении за их текущим состоянием.
Представление (вид) обычно проектируется в виде пользовательского интерфейса, такого как разметка и шаблоны, но не интерактивного. Они должны знать о существовании Моделей, но непосредственно не общаться с ними.
Контроллеры (диспетчеры) обрабатывают входные данные (клики, пользовательские действия) в приложении, а Представления можно рассматривать как выходной продукт обработки. Когда Контроллер меняет состояние Модели (например, редактирование заголовка на фото), он прямо не меняет Представление. Это — случай, где работают отношения Модели и Представления.
MVC-фреймворки на Javascript, помогающие в структурировании кода, не всегда строго следуют описанному образцу. У некоторых Контроллер будет отвечать за Представление (backbone.js), самоуверенно смешивая компоненты, считая, что так пока будет лучше.
Поэтому мы именуем такие фреймворки паттернами MV*, то есть, Представление и Модель, скорее всего, будут, но к ним добавится что-то другое (чем просто Контроллер --прим. перев.).
Замечание . существует вариант MVC под названием MVP (Model — View — Presenter) и MVVM (Model — View — ViewModel). Если Вы плохо знакомы с этими понятиями и противитесь принять их на веру, не волнуйтесь. Понадобится время, чтобы освоиться с паттернами; я написал побольше о них в моем онлайн-учебнике "Learning JavaScript Design Patterns" на случай, если Вам понадобится помощь. |
O MVC
Паттерн Модель-представление-контроллер или по-английски Model-view-controller используется очень давно. Еще в 1979 году его описал Тригве Реенскауг в своей работе «Разработка приложений на Smalltalk-80: как использовать Модель-представление-контроллер». С тех пор паттерн зарекомендовал себя как очень удачная архитектура программного обеспечения.
Пользователь, работая с интерфейсом, управляет контроллером, который перехватывает действия пользователя. Далее контроллер уведомляет модель о действиях пользователя, тем самым изменяя состояние модели. Контроллер также уведомляет представление. Представление, используя текущее состояние модели, строит пользовательский интерфейс.
Основой паттерна является отделение модели данных приложения, его логики и представления данных друг от друга. Таким образом, следуя правилу «разделяй и властвуй», удается строить стройное программное обеспечение, в котором, во-первых, модель не зависит от представления и логики, а во-вторых, пользовательский интерфейс надежно отделен от управляющей логики.
Советы
Как задать на странице html-элемент select
Первый параметр задает строку, которая добавится в список элемента, как строка по умолчанию, второй параметр – это имя нашего select.
Самое интересно заключается в том, как добавить для select данные. Допустим, мы имеем следующую модель данных:
* This source code was highlighted with Source Code Highlighter .
Где
GetProducts – это некий метод, источник данных в виде IEnumerable, такие источники данных следует располагать в модели данных, здесь приведено упрощенно для примера;
SelectList – это вспомогательный класс определенный в System.Web.MVC.
Здесь, через ViewData передается набор данных созданных с помощью класса SelectList, конструктор которого через первый параметр принимает данные в виде products. Имена свойств, определенных в классе Product, для значений и выводимого текста в select передается вторым и третьим параметрами.
Как отобразить пользовательский элемент управления
Для того чтобы отобразить свой элемент управления используется представленный в preview 5 метод Html.RenderPartial(. ). Для того чтобы использовать пользовательский элемент управления в своих проектах он должен быть создан как MVC View User Control, а не как обычный Web User Control. Разница заключается в том, от какого класса наследуется созданный элемент. В случае MVC, элемент будет наследоваться от System.Web.Mvc.ViewUserControl.
Вывод пользовательского элемента не составляет труда:
Где SampleUserCtrl – это имя класса, который представляет пользовательский элемент управления.
Как присвоить элементу, созданному через класс Html, атрибут class
Хэлпер класс HTML – это очень полезный инструмент MVC Framework, который позволяет единообразно создавать элементы управления на странице. И, конечно, методы этого класса позволяет задавать атрибуты html-элементов. На примере, мы зададим гиперссылке с текстом SampleLink, действием ActionName с параметром product.Id тэг rel = «nofollow».
Когда мало ViewData
Иногда, требуется передать данные от одного action к другому. Скажем, на странице с полем ввода во время обработки введенных данных у нас произошла исключительная ситуация, о которой необходимо сообщить, вернувшись обратно на страницу. Так как обработкой введенных данных занимался один action, а обработкой страницы заведует другой, то, используемая в иных случаях ViewData, нам не поможет.
Для таких случаев в MVC существует TempData, структура данных, которая существует только во время запроса и потом удаляется.
* This source code was highlighted with Source Code Highlighter .
Разделяем логику GET и POST запросов
[AcceptVerbs( "GET" )]
public ActionResult Login()
return View( "Index" );
>
[AcceptVerbs( "POST" )]
public ActionResult Login( string userLogin, string userPass)
[… реализуем логику …]
return RedirectToAction( "Index" , "Home" );
>
* This source code was highlighted with Source Code Highlighter .
Управление кэшированием
* This source code was highlighted with Source Code Highlighter .
Сложные страницы и пользовательские модели
Такие данные при хранении в базах данных хранятся не в одной таблице, а в нескольких, может даже в нескольких десятках. В таком случае, если вы используете ОRM – объектную модель базы данных, то для создания одной страницы MVC Framework вам придется инициализировать множество списочных или других переменных и заполнить их данными.
Я рекомендую в таком случае сделать свою комплексную модель данных, реализовав букву M из слова MVC. Ниже я приведу пример одного из вариантов реализации такой модели:
public class BankInfoModel
public Bank Bank;
public IEnumerable BankBranches;
>
* This source code was highlighted with Source Code Highlighter .
Создается модель, которая содержит значение Bank и перечисление всех отделений этого банка (допустим, по ряду причин, мы не можем получить список отделений просто через Bank).
Для прозрачного использования нашей модели мы должны сделать следующее: переделать базовый класс нашего представления с
* This source code was highlighted with Source Code Highlighter .
Теперь, в коде представления, нам доступен инстанцированный экземпляр модели типа BankInfoModel через ViewData.Model. Конечно, контроллер должен его инициализировать для нас, но это элементарно:
public ActionResult Info( int ? id)
var info = new BankInfoModel x.id == id)>;
info.BankBranches = info.Bank.LocationBranches
.Where(x => x.Address.Street.cityId == 1).SelectMany(x => x.BankBranches);
* This source code was highlighted with Source Code Highlighter .
Где int? id – это параметр, который указывает на идентификатор банка
Использование экземпляра нашей модели в представлении также просто:
* This source code was highlighted with Source Code Highlighter .
Сложные типы, ModelBinder
MVC Framework так устроен, что передача значений формы производится через параметры action. Например, ниже представлена форма с двумя полями для ввода данных логина и пароля.
* This source code was highlighted with Source Code Highlighter .
Данные, которые пользователь ввел в этой форме, передадутся в action через соответствующие параметры, так как показано ниже:
Но что делать, когда форма содержит десятки вводимых полей? Неужели создавать десятки параметров у action? Нет, MVC Framework содержит механизм, который позволяет избежать такого некрасивого шага, как многочисленные параметры метода. Такой механизм называется ModelBinder. Для начала объявим класс, описывающий нашу форму:
* This source code was highlighted with Source Code Highlighter .
public class LoginModelBinder : IModelBinder
public object GetValue(ControllerContext controllerContext, string modelName,
Type modelType, ModelStateDictionary modelState)
LoginModel modelData = new LoginModel ();
modelData.userLogin = controllerContext. HttpContext .Request[ "userLogin" ];
modelData.userPass = controllerContext. HttpContext .Request[ "userPass" ];
* This source code was highlighted with Source Code Highlighter .
Обратите внимание, мы определяем метод GetValue и заполняем в нем данные модели через контекст запроса.
Перед заключительным шагом нам необходимо указать для нашего класса модели LoginModel атрибут ModelBinder:
[ModelBinder( typeof (LoginModelBinder))]
public class LoginModel
public string userLogin < get ; set ; >
public string userPass
* This source code was highlighted with Source Code Highlighter .
В заключение, используем наши конструкции для автоматической инициализации параметров переданных с формы:
[AcceptVerbs(«POST»)]
public ActionResult Login([ModelBinder(typeof(LoginModelBinder))] LoginModel loginModelData)
Кроме того, для разработчиков доступен атрибут Bind, который позволяет управлять префиксом имен параметров формы, так что возможно изменить его значение или указать, что префикса не будет вовсе. Этот же атрибут позволяет задавать «белые» или «черные» списки свойств формы, которые будут связываться со значениями параметра комплексного типа.
И хотя мы не обязаны создавать свои варианты ModelBinder этот инструмент все же может пригодиться и будет полезным для тонкой настройки обработки значений комплексных типов переданных с формы.
Перехват необработанных ошибок, неверных URL
Для перехвата необработанных исключений необходимо создать в папке Views/Shared страницу Error.aspx с информацией об ошибке, которая содержит, например, такой код:
* This source code was highlighted with Source Code Highlighter .
Для того, чтобы все необработанные исключения перенаправлялись на нашу страницу необходимо каждому контроллеру указать атрибут HandleError:
Далее, чтобы обрабатывать все неверные URL, которые не подпадают под наш маршрут заданный в global.asax, необходимо создать еще один маршрут, который бы направлял все неверные запросы на специальную страницу:
* This source code was highlighted with Source Code Highlighter .
* This source code was highlighted with Source Code Highlighter .
Таким образом, мы отловим попытки переходов по неверному маршруту, но что делать, если маршрут попадает под шаблон, но все равно неверен? Выходом может стать проверка на местах с генерацией исключения:
public ActionResult Info( int ? id)
if (!id.HasValue)
throw new HttpException( "404" );
* This source code was highlighted with Source Code Highlighter .
Для перехвата такого пользовательского исключения необходимо создать или изменить в web.config раздел customErrors:
* This source code was highlighted with Source Code Highlighter .
Проверка модели
Платформа обрабатывает проверку данных запроса на клиенте и на сервере. Логика проверки, указанная в типах модели, добавляется в готовые для просмотра представления в виде ненавязчивых заметок и реализуется в браузере с помощью подключаемого модуля jQuery Validation.
Model validation
A controller action:
The framework handles validating request data both on the client and on the server. Validation logic specified on model types is added to the rendered views as unobtrusive annotations and is enforced in the browser with jQuery Validation.
Razor обработчик представлений
С помощью обработчика представлений Razor можно определить макеты, частичные представления и заменяемые разделы.
■ Когда нам нужен MV*-фреймворк JS?
В начале работы не очень трудно написать каркас (фреймворк) приложения, предлагающий некоторый велосипед механизм для избегания спагетти-кода. Но говорить, что это не сложнее, чем написать «какой-нибудь» Backbone, было бы слишком неправильно.
Есть нечто намного большее в структурированных приложениях, чем связывание манипуляций DOM, шаблонизации и выявление связей. Зрелые фреймворки MV* обычно не только содержат много кусочков, которые вы бы написали, но и содержат решения будущих задач. Это экономит время, что нельзя недооценивать.
Маршрутизация
Маршрутизация на основе соглашений позволяет глобально определять форматы URL-адресов, которые принимает приложение, и как каждый из этих форматов сопоставляется с определенным методом действия на заданном контроллере. При поступлении входящего запроса модуль маршрутизации выполняет синтаксический анализ URL-адреса и соотносит его с одним из определенных форматов URL-адресов, а затем вызывает метод действия связанного контроллера.
Маршрутизация атрибутов используется для указания сведений о маршрутизации путем добавления атрибутов, определяющих маршруты приложения, к контроллерам и действиям. Это означает, что определения маршрутов помещаются рядом с контроллером и действием, с которым они связаны.
Areas
Компоненты представлений
Компоненты представлений позволяют упаковывать логику отрисовки и повторно использовать ее в приложении. Они аналогичны частичным представлениям, но имеют связанную логику.
■ Проблема выбора: слишком много вариантов?
В моем топике “Классификация JavaScript MVC: Злоупотребление или Развитие?” (англ.), я поднял вопрос о том, что сейчас есть слишком большой выбор инструментов для структурирования вашего JS-приложения. Часть проблемы истекает из того, как различные разработчики JavaScript выбирают организацию масштабируемого приложения: MVC, MVP, MVVM? Или что-то другое? Каждую неделю с большим избытком рождаются новые MV*-фреймворки, потому что мы всё ищем “правильный путь”, если он существует вообще. Много разработчиков полагают, что его нет.
Мы идём выбирать новые фреймворки, которые часто возникают как ‘Yet Another Framework Syndrome’ (или YAFS). На правах инноваций кое-что, конечно, приветствуется, но YAFS может привести к большой растерянности и фрустрации, когда разработчики хотят начать писать приложение, а им надо вручную оценить 30 инструментов, чтобы выбрать что-нибудь не сильно неподходящее. Различия между некоторыми фреймворками будут очень тонкими, если не трудноразличимыми.
Model binding
Фильтры
Фильтры помогают разработчикам решать общие задачи, такие как обработка исключений или авторизация. Фильтры активируют пользовательскую логику предварительной и завершающей обработки для методов действий и могут быть настроены для запуска в определенные моменты в конвейерном выполнении определенного запроса. Фильтры могут применяться к контроллерам или действиям в виде атрибутов (или могут выполняться глобально). В состав платформы входит несколько фильтров (например, Authorize ). [Authorize] является атрибутом, который используется для создания фильтров авторизации MVC.
Tag Helpers
Tag Helpers enable server side code to participate in creating and rendering HTML elements in Razor files. You can use tag helpers to define custom tags (for example, ) or to modify the behavior of existing tags (for example, ). Tag Helpers bind to specific elements based on the element name and its attributes. They provide the benefits of server-side rendering while still preserving an HTML editing experience.
The EnvironmentTagHelper can be used to include different scripts in your views (for example, raw or minified) based on the runtime environment, such as Development, Staging, or Production:
Tag Helpers provide an HTML-friendly development experience and a rich IntelliSense environment for creating HTML and Razor markup. Most of the built-in Tag Helpers target existing HTML elements and provide server-side attributes for the element.
Функции контроллера
Контроллеры — это компоненты для управления взаимодействием с пользователем, работы с моделью и выбора представления для отображения. В приложении MVC представление служит только для отображения информации. Обработку введенных данных, формирование ответа и взаимодействие с пользователем обеспечивает контроллер. В структуре MVC контроллер является начальной отправной точкой и отвечает за выбор рабочих типов моделей и отображаемых представлений (именно этим объясняется его название — он контролирует, каким образом приложение отвечает на конкретный запрос).
Контроллеры не должны быть чересчур сложными из-за слишком большого количества обязанностей. Чтобы не перегружать логику контроллера, перенесите бизнес-логику из контроллера в модель предметной области.
Если ваш контроллер часто выполняет одни и те же виды действий, переместите эти действия в фильтры.
■ Где же мы будем нуждаться в MV*, а где нет?
Если вы пишете приложение для общения с API или для обработки данных бекенда, где основная тяжесть просмотра или управления данными будет в браузере, в нём JavaScript MV*-фреймворк будет полезным.
Хорошие примеры приложений этого рода — Google Docs и GMail. Обычно такие приложения загружают один раз полезный груз со всеми скриптами, стилями и разметкой для общих задач и затем выполняют много мелких действий в фоне страницы. Это — просто переходы с чтения почты или документа на составление писем, и вам вообще не нужно загружать новые страницы.
Но если вы строите приложение, которому требуется сервер для большого объёма Представлений (страниц) и используете небольшой JavaScript или jQuery для обмена, паттерн MV может стать убийственным. Конечно, есть сложные приложения в вебе, где частичный показ представлений МОЖЕТ хорошо жить вместе с одностраничным приложением, но для всего остального лучше выбрать механизм загрузки попроще.
Routing
Convention-based routing enables you to globally define the URL formats that your application accepts and how each of those formats maps to a specific action method on a given controller. When an incoming request is received, the routing engine parses the URL and matches it to one of the defined URL formats, and then calls the associated controller's action method.
Attribute routing enables you to specify routing information by decorating your controllers and actions with attributes that define your application's routes. This means that your route definitions are placed next to the controller and action with which they're associated.
Compatibility version
Функции представления
MVC pattern
The Model-View-Controller (MVC) architectural pattern separates an application into three main groups of components: Models, Views, and Controllers. This pattern helps to achieve separation of concerns. Using this pattern, user requests are routed to a Controller which is responsible for working with the Model to perform user actions and/or retrieve results of queries. The Controller chooses the View to display to the user, and provides it with any Model data it requires.
The following diagram shows the three main components and which ones reference the others:
This delineation of responsibilities helps you scale the application in terms of complexity because it's easier to code, debug, and test something (model, view, or controller) that has a single job. It's more difficult to update, test, and debug code that has dependencies spread across two or more of these three areas. For example, user interface logic tends to change more frequently than business logic. If presentation code and business logic are combined in a single object, an object containing business logic must be modified every time the user interface is changed. This often introduces errors and requires the retesting of business logic after every minimal user interface change.
Both the view and the controller depend on the model. However, the model depends on neither the view nor the controller. This is one of the key benefits of the separation. This separation allows the model to be built and tested independent of the visual presentation.
Функции модели
Модель в приложении MVC представляет состояние приложения и бизнес-логику или операций, которые должны в нем выполняться. Бизнес-логика должна быть включена в состав модели вместе с логикой реализации для сохранения состояния приложения. Как правило, строго типизированные представления используют типы ViewModel, предназначенные для хранения данных, отображаемых в этом представлении. Контроллер создает и заполняет эти экземпляры ViewModel из модели.
Привязка модели
■ TodoMVC: общее приложение для обучения и сравнения
Мы видим огромный бум в количестве таких MV*-фреймворков за последние несколько лет.
Backbone.js, Ember.js, AngularJS, Spine, CanJS… Список новых и работоспособных решений растёт каждую неделю; разработчики могут быстро потеряться в море вариантов. Им есть из чего выбирать. Имеется много сильных конкурирующих решений от умов, работавших над сложными приложениями, которые вдохновили на создание библиотек (такие как Yehuda Katz и Джереми Ashkenas). Вопрос: что использовать и как выбирать?
Мы осознали это положение и захотели помочь разработчикам максимально упростить процесс выбора. Мы создали TodoMVC — проект, который реализует одно и то же приложение Todo на различных популярных на сегодня MV*-фреймворках. Считайте его измерителем скорости работы с данными для фреймворков. Реализации живут и работают одинаково и помогают нам сравнивать синтаксис и структуру различных фреймворков; таким образом, мы можем выбрать тот, который чувствуется самым удобным или, по крайней мере, сравнение поможет сузить круг выбора.
На этой неделе (14 июл.2012) мы выпускаем совершенно новую версию TodoMVC, подробности которой приводятся ниже в разделе приложений.
В ближайшем будущем мы хотим развить работу далее, предоставляя заметки о различиях и рекомендации о том, для каких типов приложений следует рассматривать вариант использования того или другого фреймворка.
Шаблон MVC
Структура архитектуры MVC разделяет приложение на три основных группы компонентов: модели, представлении и контроллеры. Это позволяет реализовать принципы разделения задач. Согласно этой структуре запросы пользователей направляются в контроллер, который отвечает за работу с моделью для выполнения действий пользователей и (или) получение результатов запросов. Контроллер выбирает представление для отображения пользователю со всеми необходимыми данными модели.
На следующей схеме показаны три основных компонента и существующие между ними связи.
Такое распределение обязанностей позволяет масштабировать приложение в контексте сложности, так как проще писать код, выполнять отладку и тестирование компонента (модели, представления или контроллера) с одним заданием. Гораздо труднее обновлять, тестировать и отлаживать код, зависимости которого находятся в двух или трех этих областях. Например, логика пользовательского интерфейса, как правило, подвергается изменениям чаще, чем бизнес-логика. Если код представления и бизнес-логика объединены в один объект, содержащий бизнес-логику, объект необходимо изменять при каждом обновлении пользовательского интерфейса. Это часто приводит к возникновению ошибок и необходимости повторно тестировать бизнес-логику после каждого незначительного изменения пользовательского интерфейса.
Представление и контроллер зависят от модели. Однако сама модель не зависит ни от контроллера, ни от представления. Это является одним из ключевых преимуществ разделения. Такое разделение позволяет создавать и тестировать модели независимо от их визуального представления.
Выбор времени создания приложения MVC
Перед использованием платформы MVC или модели веб-форм для определенного веб-сайта следует взвесить все преимущества каждого из подходов.
Внедрение зависимостей
Кроме того, приложение может использовать внедрение зависимостей в файлы представления с помощью директивы @inject :
■ Предложенные нами критерии выбора фреймворка
Выбор фреймворка — конечно, больше, чем простое сравнение работы приложения ToDo. Поэтому, когда ваш выбор оставит нескольких кандидатов, рекомендуем немного отойти от работы и осмотреться. Возможно, фреймворку придётся поддерживать нетривиальные функции, и может оказаться, что его придётся поддерживать долгие годы. Попробуйте ответить на вопросы.
На что действительно способен фреймворк?
Потратьте время на чтение исходного кода фреймворка и официального списка возможностей, чтобы узнать, насколько они соответствуют вашим требованиям. Будут проекты, которые могут потребовать изменения или дополнения исходного кода, и если вы посчитали это для себя выполнимым, код прошёл проверку.
Был ли проверен фреймворк в работе?
Есть ли разработчики, построившие и внедрившие большие, публично доступные приложения с этой библиотекой? Backbone имеет серьёзный список таких (SoundCloud, LinkedIn), но не все имеют подобное. Ember работает в ряде больших приложений, включая инструменты пользователя в Square. JavaScriptMVC используется в крупных приложениях в IBM, не считая других мест. Важно не только знать, что фреймворк работает, но и иметь возможность смотреть на реальный код и понимать, как это может быть построено.
Фреймворк отработан?
Мы рекомендуем разработчикам не просто “выбрать это и пойти работать”. Новые проекты часто сопровождаются множеством обсуждений релизов, не забудьте о них, выбирая релиз для приложения продакшн-уровня. Вы же не хотите иметь в проекте риск быть остановленным из-за срочного рефакторинга или других поломок, которые более предсказуемы, если фреймворк отработан, отлажен. Зрелые проекты обычно лучше документированы, официально или через сообщество.
Фреймворк гибкий или жёсткий в управлении?
Знайте, что есть библиотеки разного «характера». Фреймворки с жёстким управлением хотят от вас программирования в определённых рамках. Они ограничивают дизайн приложения и меньше уделяют внимание разработчикам, самостоятельно выясняющим, как это должно работать.
Вы действительно «поигрались» с фреймворком?
Напишите маленькое приложение, без фреймворка и затем попробуйте переделать код на работу с фреймворком, чтобы оценить, легко ли с ним работать. Поскольку работа с кодом повлияет на ваше решение, важно написать работающий код, чтобы убедиться, что вам удобно работать с его конструкциями.
Есть ли полная документация?
Хотя демо-приложения полезны для ссылки и просмотра, вы почти всегда будете общаться с официальными разработчиками фреймворка, узнавать, о поддержке API, о том, как решать общие задачи, как создавать компоненты и какие есть замеченные баги. Любой стОящий фреймворк должен иметь подробную документацию, помогающую разработчикам разобраться в нём. Без неё вы можете найти IRC-каналы с группами разработчиков или проводить самостоятельные исследования, которые сами по себе прекрасны, но часто отнимают много времени по сравнению с заранее предоставленным набором документов.
Каков объём фреймворка, способность к минификации, сжатию, модульности?
Какие зависимости имеет фреймворк?
Для фреймворков есть тенденция указывать размер их файла, но не упоминать размеры библиотек зависимостей. Маленькая библиотека окажется неожиданно большой, если, скажем, зависит от jQuery или других библиотек.
Вы ознакомились с сообществом пользователей-разработчиков фреймворка?
Есть ли активное сообщество участников проекта и пользователей, которые были бы в состоянии помочь, если будут проблемы? Достаточно ли много разработчиков использовали фреймворк, есть ли ссылки на работающие приложения, обучающие программы и, возможно, даже скринкасты, чтобы узнать о нём больше?
Заключение
В статье я попытался описать некоторые аспекты работы с MVC Framework. Многие моменты – элементарны, некоторые не так просты, как кажутся, часть – хорошо описана в интернете, часть – не описана вовсе. Во всех случаях приведенный материал может сослужить хорошую службу как начинающим знакомство с MVC Framework, так и тем, кто уже имеет опыт создания web-приложений с его помощью.
MVC Framework сегодня – это, всего лишь, бета-версия того продукта, который будет в итоге. Но уже сейчас этот инструмент позволяет создавать web-приложения, используя все мощь паттерна MVC. Возможно, когда вы будете читать эту статью, выйдет финальный релиз MVC Framework, который ожидается к концу 2008 года, но можно предположить, что большинство функций уже не будет изменено.
Web APIs
Use link generation to enable support for hypermedia. Easily enable support for cross-origin resource sharing (CORS) so that your Web APIs can be shared across multiple Web applications.
Testability
The framework's use of interfaces and dependency injection make it well-suited to unit testing, and the framework includes features (like a TestHost and InMemory provider for Entity Framework) that make integration tests quick and easy as well. Learn more about how to test controller logic.
View Responsibilities
■ Dojo и усложнение фреймворков на JavaScript
Как многие знают, Dojo Toolkit была одной из первых попыток дать разработчикам средство разработки сложных приложений. Некоторые могут сказать, что это вдохновило их больше думать о задачах для необычных приложений. Я спрашивал [в письме] разработчиков Dojo — Dylan Schiemann, Kitson Келли, и Джеймса Томаса, что они думают о появлении MV*-фреймворков.
В.: Библиотека Dojo не могла всё это решить? Почему она не стала предпочтительным решением для желающих построить более структурированные и нетривиальные приложения?
О.: Несколько лет назад, когда окружение JavaScript развилось от добавления простого Ajax и эффектов на странице, Dojo проповедовал «инструментальный» подход к построению сложных приложений в Вебе.
Многие из тех функций были далеко впереди большинства потребностей разработчиков. С появлением браузера как доминирующей платформы приложения, многие новшества ввели в Dojo Toolkit, а теперь они появляются в новых инструментах. MVC был просто ещё одним пакетом, который предоставляла Dojo достаточно долгое время вместе с другими модулями кода: OOП в JS, виджетов UI, кроссбраузерной графики, шаблонов, интернационализации, доступа к данным, хранилищ данных, тестовых фреймворков, сборки системы и очень многого другого.
Джаваскрипт-библиотеки не должны иметь «претензии», почему Dojo с ранней стадии сконцентрировала усилия на полном цикле разработки приложений уровня предприятия. Тот же фокус имеется сейчас и у MVC, просто это один «инструмент из набора».
Почему Dojo — не доминирующий набор инструментов? Её цель никогда не состояла в том, чтобы стать единственным выбором. Цель была в том, чтобы обеспечить открытый набор инструментов, могущих работать с чем-нибудь другим в пределах проектов и с переносимостью в другие проекты. Dojo критиковалась за то, что была медленной и даже после того, как за это взялись, она критиковалась за то, что была медленной. Попытка избавиться от ярлыка — сложная задача. Трудно документировать особенности богатого набора инструментов. В Dojo 1.8 — 175 суб-пакетов и более 1 400 модулей.
Это не только вопрос о достижении цели документирования, он значит, что Dojo решает не одну задачу. Хорошо, когда вы пишете программу, но очень трудно сначала выяснить, с чего начать. Улучшенная документация и обучающие программы пытаются помочь в работе с Dojo 1.8.
В.: Почему разработчики должны выбрать Dojo и какой список идей вы имеете для будущего проекта? Говорят, что после 1.8 будет другая цель.
О.: В Dojo 1.8 пакет dojox/mvc делает ещё один шаг к зрелости. Много было затрачено времени, усилий, тестирования и внимания сообщества к пакету. Он специализируется на предоставлении модели MVC, усиливающей остальную часть Dojo. Вместе с прикладным пакетом dojox/app для построения rich-приложений для десктопов и мобильных устройств, это делает целостную систему для клиентской стороны.
И это — только один из жизнеспособных путей построения приложений в типичном подходе Dojo.
В 1.8, мало того, что подмодуль MVC становится более зрелым, он основан на устойчивом фреймворке. Это не только дает язык разметки, чтобы создать Ваши View-компоненты, выразить Ваши модели или разработать контроллер. Это намного больше, чем просто подключить ещё один модуль к источнику данных. Поскольку это подключено к остальной части Dojo, вы можете подключить всё, что потребуется.
В Dojo 2.0 мы будем пробовать поднять модульность на новый уровень, чтобы стало еще проще взять то, другое и собрать всё это вместе. Мы также исследуем концепцию изоморфизма, чтобы для пользователя не имело значения, где выполняется код, на клиенте или сервере, и, в конечном счете, это должно быть прозрачно разработчику.
Razor view engine
Using the Razor view engine you can define layouts, partial views and replaceable sections.
Тестирование
Благодаря используемым интерфейсам и внедрению зависимостей платформа хорошо подходит для модульного тестирования. Кроме того, с помощью таких компонентов, как TestHost и поставщик InMemory для Entity Framework, можно быстро и просто выполнять интеграционные тесты. Узнайте больше о тестировании логики контроллеров.
Filters
Filters help developers encapsulate cross-cutting concerns, like exception handling or authorization. Filters enable running custom pre- and post-processing logic for action methods, and can be configured to run at certain points within the execution pipeline for a given request. Filters can be applied to controllers or actions as attributes (or can be run globally). Several filters (such as Authorize ) are included in the framework. [Authorize] is the attribute that is used to create MVC authorization filters.
Версии MVC Framework
Строго типизированные представления
Razor представления в MVC могут быть строго типизированы на основе модели. Контроллеры передают строго типизированную модель в представления для поддержки в них IntelliSense и проверки типов.
Например, следующее представление отображает модель типа IEnumerable :
■ Что такое MVC или, лучше сказать, MV*?
Эти современные библиотеки дают разработчикам простой путь к организации кода, используя вариации паттерна проектирования, известного как MVC (Model-View-Controller). MVC разделяет задачи в приложении на 3 части:
Модель (логика) представляют проблемно-ориентированные знания и данные в приложении. Думайте о них как о типе данных, которые сможете смоделировать, о таких, как Пользователь, Фото, или Замечание. Модели должны информировать о чём-либо при наблюдении за их текущим состоянием.
Представление (вид) обычно проектируется в виде пользовательского интерфейса, такого как разметка и шаблоны, но не интерактивного. Они должны знать о существовании Моделей, но непосредственно не общаться с ними.
Контроллеры (диспетчеры) обрабатывают входные данные (клики, пользовательские действия) в приложении, а Представления можно рассматривать как выходной продукт обработки. Когда Контроллер меняет состояние Модели (например, редактирование заголовка на фото), он прямо не меняет Представление. Это — случай, где работают отношения Модели и Представления.
MVC-фреймворки на Javascript, помогающие в структурировании кода, не всегда строго следуют описанному образцу. У некоторых Контроллер будет отвечать за Представление (backbone.js), самоуверенно смешивая компоненты, считая, что так пока будет лучше.
Поэтому мы именуем такие фреймворки паттернами MV*, то есть, Представление и Модель, скорее всего, будут, но к ним добавится что-то другое (чем просто Контроллер --прим. перев.).
Замечание . существует вариант MVC под названием MVP (Model — View — Presenter) и MVVM (Model — View — ViewModel). Если Вы плохо знакомы с этими понятиями и противитесь принять их на веру, не волнуйтесь. Понадобится время, чтобы освоиться с паттернами; я написал побольше о них в моем онлайн-учебнике "Learning JavaScript Design Patterns" на случай, если Вам понадобится помощь. |
Совместимая версия
В состав платформы MVC входят следующие компоненты.
Рис. 01. Вызов действия контроллера, ожидающего значения параметра (щелкните для просмотра полноразмерного изображения)
- Модели. Объекты модели — это части приложения, реализующие логику для домена данных приложения. Объекты моделей часто получают и сохраняют состояние модели в базе данных. Например, объект Product может извлекать сведения из базы данных, работать с ней, а затем записывать обновленные сведения в таблицу Products в SQL Server.
В небольших приложениях эта модель подразумевает концептуальное, а не физическое разделение. Например, если приложение считывает только набор данных и отправляет его в представление, приложение не имеет физического уровня модели и связанных классов. В этом случае набор данных принимает роль объекта модели.
Представления. Представления — это компоненты, отображающие пользовательский интерфейс приложения. Пользовательский интерфейс обычно создается на основе данных модели. Примером может быть представление редактирования таблицы Products, в котором отображаются текстовые поля, раскрывающиеся списки и флажки на основе текущего состояния объекта Products.
Контроллеры. Контроллеры осуществляют взаимодействие с пользователем, работу с моделью, а также выбор представления, отображающего пользовательский интерфейс. В приложении MVC представление служит только для отображения информации. Обработку введенных данных, формирование ответа и взаимодействие с пользователем обеспечивает контроллер. Например, контроллер обрабатывает значения строки запроса и передает эти значения в модель, которая, в свою очередь, запрашивает базу данных с помощью значений.
Шаблон MVC позволяет создавать приложения, различные аспекты которых (логика ввода, бизнес-логика и логика интерфейса) разделены, но достаточно тесно взаимодействуют друг с другом. Эта схема указывает расположение каждого вида логики в приложении. Логика пользовательского интерфейса относится к представлению. Логика ввода относится к контроллеру. Бизнес-логика размещается в модели. Это разделение позволяет работать со сложными структурами при создании приложения, так как обеспечивает одновременную реализацию только одного аспекта. Например, разработчик может сконцентрироваться на создании представления отдельно от бизнес-логики.
Связь между основными компонентами приложения MVC также облегчает параллельную разработку. Например, один разработчик может работать над представлением, второй разработчик может работать над логикой контроллера, а третий разработчик может сосредоточиться на бизнес-логике в модели.
Model Responsibilities
The Model in an MVC application represents the state of the application and any business logic or operations that should be performed by it. Business logic should be encapsulated in the model, along with any implementation logic for persisting the state of the application. Strongly-typed views typically use ViewModel types designed to contain the data to display on that view. The controller creates and populates these ViewModel instances from the model.
View Components
View Components allow you to package rendering logic and reuse it throughout the application. They're similar to partial views, but with associated logic.
Вспомогательные функции тегов
Вспомогательные функции тегов позволяют коду на стороне сервера участвовать в создании и отрисовке HTML-элементов в Razor файлах. Вспомогательные функции тегов используются для определения настраиваемых тегов (например, ) или для изменения поведения существующих тегов (например, ). Вспомогательные функции тегов привязываются к определенным элементам на основе имени элемента и его атрибутов. Они предоставляют преимущества отрисовки на стороне сервера, сохраняя при этом возможности редактирования HTML.
С помощью EnvironmentTagHelper можно включать в приложения различные сценарии (например, необработанные или минифицированные) для конкретной среды выполнения (разработки, промежуточной или производственной):
Вспомогательные функции тегов предоставляют удобный для HTML интерфейс разработки и полнофункциональные среды IntelliSense для создания HTML и Razor разметки. Большинство встроенных вспомогательных функций тегов работают с существующими HTML-элементами и предоставляют для них атрибуты на стороне сервера.
■ Коллекция TodoMVC
В нашем совершенно новом выпуске теперь имеются реализации Todo для самых популярных фреймворков с большим количеством других умеренно используемых фреймворков, запущенных в Labs. Эти реализации прошли много пересмотров, часто принимая «на борт» подсказки из лучших практик и предложения от авторов фреймворка, участников его разработки и пользователей сообщества.
Вслед за комментариями, сделанными автором Backbone.js Jeremey Ashkenas и Yehuda Katz, TodoMVC теперь тоже предлагает соответствующие реализации, сделанные на официальной спецификации приложения, такие как навигация (или управление состояниями). (?)
Мы не делаем вид, что более сложные приложения для сравнения невозможны (конечно, возможны), но простота приложения Todo позволяет разработчикам воспринимать структуру кода, синтаксис компонентов и «чувство потока» в достаточной степени, чтобы начать сравнивать фреймворки и смотреть детали их решений или нескольких решений.
(Тут придётся остановиться на самом интересном месте — размер текста растёт — чтобы прекратить дозволенные речи. Сразу после перерыва будет задан самый ожидаемый вопрос современности: какой фреймворк когда следует использовать? 9 восхитительных одноблочных сентенций, обёрнутых фразой «Я хочу. », завершённые умопомрачительным соусом «Используйте . » в рецептах от самого Эдди Османи!)
Далее, в заключительной части:
■ Какой фреймворк когда следует использовать?
■ Что разработчики думают о самых популярных фреймворках? («за» и «против»)
■ Не бойтесь экспериментировать
■ Выход за пределы MV*
■ Заключение.
Похожий обзор: Rich JavaScript Applications – the Seven Frameworks (Throne of JS, 2012), Steven Sanderson, 1th Aug 2012. Различия и совпадения подходов Backbone, Meteor, Ember, AngularJS, Knockout, Spine, Batman, CanJS — по результатам конференции «Throne of JS, 2012».
Необходимое отступление: не так давно я разместил статью предназначавшуюся для печатного издания. Приведенная ниже статья имеет ту же самую судьбу: она не попала в печать в связи с тяжелым положением журнала. Как и в прошлый раз, я решил опубликовать статью на Хабре, благо тематика попадает под формат. Необходимо заметить, что статья оформлена и содержит текст для журнала, если бы она готовилась для Хабра, то некоторые часть могли бы быть изменены. Надеюсь, статья вам понравится.
Читайте также: