среда, 19 ноября 2014 г.

Применение шаблона MVP в ASP.NET Webforms

В предыдущих постах знакомство с шаблоном MVP-VM, проводилось на наиболее подходящей для этого технологии Windows forms. Я неслучайно стал использовать эту технологию в качестве демонстрационной площадки, т.к. самые вопиющие нарушения принципа разделения ответственностей (Separation of Concerns) я наблюдал в проектах, использующих в качестве UI, Windows forms и ASP.NET Web forms. Дизайн таких проектов представляет кашу кода из доменной, инфраструктурной, презентационной логики в code behind’е форм, aka Smart UI. И все бы ничего до поры до времени, пока в результате экспоненциального роста сложности не начинают расти бюджеты ресурсов (деньги, люди) на поддержку проекта в ущерб развитию.

Описанные проблемы являются следствием пренебрежительного отношения к законам разработки программного обеспечения. В условиях постоянно расширяющегося проекта должны быть четко заданы параметры качества, в частности дизайна: концептуальная целостность, удобство и простота обслуживания, возможность повторного использования и пр., которые определят перечень законов разработки необходимых для удержания заданных границ качества. Но зачастую параметры качества дизайна никак формализованы, по принципу «ну это и так всем понятно!». А поскольку нет критериев качества, то нет и законов их соблюдения, нет проработки дизайна. И, первый закон, которого нет  - принцип единственной обязанности SRP (Single Responsibility Principle),  базовой целью которого является борьба со сложностью.

Следуя цели упрощения, для организации уровня представления, необходимо применять структурно-проектировочные шаблоны, такие как MVC и MVP, в которых ответственность за обработку задач UI разбивается на три роли: модель, представление, контроллер/презентер.

В данном посте я хочу обобщить описанные ранее практики разграничения ответственностей уровня представления на простом примере - фронта’ web приложения по схеме шаблона MVP.

Задача

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

Реализуемые варианты использования 

1. Обзор списка отгруженных заказов (по регионам);
2. Обзор деталей заказа;
3. Отметка о фактической доставки;

Цели по дизайну приложения

Удобство и простота обслуживания;
Масштабируемость;
Тестируемость;

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

Выбор шаблона

При разработке дизайна уровня представления ASP.NET Webforms применяется шаблон Model-View-Presenter (MVP), он является результатом эволюционного развития MVC, который корректно разделяет представление и модель, размещая между ними презентер, выступающий в роли посредника (Mediator GoF).

Схема шаблона:

Model – на схеме domain model, модель предметной области.
View – страница ASP.NET, от System.Web.UI.Page.
Presenter – объект посредник, инкапсулирующий способ взаимодействия представления с объектами модели предметной области.

Жизненный цикл объектов 

После получения запроса страницы среда выполнения ASP.NET создаёт экземпляр представления View, потомка от System.Web.UI.Page. Выполнив инициализацию и установку свойств элементов, представление передаёт управление презентеру. Презентер запрашивает  данные, необходимые для отрисовки в модели предметной области, и настраивает представление на отображение этих данных.

Схема реализации списка заказов 

Реализация представления (View)

Представление реализует 2 основные задачи, инициализация презентера и реализация метода привязки данных к компонентам UI. Поскольку в рамках инфраструктуры asp.net web from в начале жизненного цикла страницы происходит  инициализация представления, то ответственность за передачу управления презентеру лежит на ней. Это происходит на этапе возникновения события Page_Load, когда все элементы UI станицы завершили свою инициализацию. Второй задачей является привязка данных, которая осуществляется в методе BindData в рамках контракта IView.

Реализация презентера (Presenter)


Задачей презентера является реализация вариантов использования (use case) приложения и настройка View на отображение данных. Метод инициализации получает ссылку на экземпляр представления, которым будет осуществляться управление. Метод LoadOrderList относится к реализации сценария «Обзор списка отгруженных заказов (по регионам)», в котором осуществляется запрос объектов модели, преобразование и формирование контекста данных представления (в сложных сценариях ViewModel), вызов метода привязки данных к элементам пользовательского интерфейса - View.BindData().

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

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

Заключение

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

P.S.
Неоднократно в качестве примеров применения шаблона MVP наблюдал демонстрации применения единого кода презентера для управления как Windows form так и ASP.NET Web forms  приложением. Хочу отметить, что такого рода примеры используются исключительно в ознакомительных целях. Не нужно принимать подобный трюк как руководство к действию, и уж тем более ни при каких обстоятельствах не стоит отдавать управление представлением Web и Decktop одному презентеру, поскольку различные архетипы приложений не интегрируются на презентационном уровне.

Исходный код демо-решения можно скачать здесь, группа Sample5.

Список используемых источников

1. Model View Presenter (MVP) VS Model View Controller (MVC)
2. Улучшение Web Forms с помощью шаблона MVP
3. Dependency Injection in ASP.NET WebForms
4. ASP.NET Dependency Injection HTTP Module

1 комментарий:

  1. Я не мог поверить, что существует настоящий онлайн-кредитор, который может быть таким добрым и честным, как Бенджамин Ли, который предоставил мне ссуду в 2 миллиона евро для выполнения моего проекта, который так долго ждал своего исполнения, но с С помощью офицера Бенджамина все было легко для меня. Я скажу вам связаться с кредитным офицером Бенджамином Ли по адресу 247officedept@gmail.com

    ОтветитьУдалить