- PVSM.RU - https://www.pvsm.ru -

Реализация MVVM в ABAP

После окончания университета я несколько лет работал программистом C#. Я разрабатывал приложения на WPF с использованием шаблона проектирования MVVM. Затем перешел на ABAP. К большому удивлению обнаружил что ABAP является скорее процедурным языком чем объектно-ориентированным, хотя SAP прилагает большие усилия для продвижения ОО-парадигмы. Для разделения бизнес-логики от GUI как правило используют архитектурный шаблон MVC. Пытаясь реализовать MVC шаблон я каждый раз сталкивался с определенными сложностями, которые делают поддержку программы еще более сложной чем если бы она была написана на процедурах. Не смотря на то, что реализация MVC подробно и с примерами описана в книге Design Patterns in ABAP Objects [1] и на специализированных ресурсах (sapland.ru [2], blogs.sap.com [3] и др.), проблемы с разделением логики остаются. В реализации MVC на ABAP независимой частью остается Model, а View и Controller тесно связаны между собой. Сильное сопряжение между View и Controller затрудняет поддержку и масштабируемость. Ниже описано почему так происходит и что с этим делать.

Шаблоны MVC и MVVM

Подробно описывать принцип работы шаблонов MVC и MVVM в данной статье я не буду. Приведу лишь основные моменты, которые понадобятся нам в дальнейшем.

Основное отличие MVC от MVVM в том, что в первой Controller знает как View, так и Model, также допускается что View будет знать о Model.

image

В MVVM шаблоне связь между слоями более слабая. View знает только ViewModel, а ViewModel только Model. View получает данные от ViewModel через ссылку на DataContex.

image

Шаблон MVVM предназначен для разработки в WPF на языке C#. Но его идею можно применять и в ABAP.

Проблемы MVC в ABAP

При реализации MVC, как правило, классы Model выносят в глобальное определение, а классы View и Controller в локальное. Использование локальных классов обусловлено необходимостью взаимодействия с GUI элементами. Дело в том, что на ABAP-классах нельзя построить полноценный GUI. В классах View можно использовать функционал для формирования GUI (CL_SALV_TABLE, REUSE_ALV_GRID_DISPLAY и т.п.), но этого не достаточно. Создать GUI-статусы, заголовки, экраны, PBO, PAI в классе невозможно.

Локальные View и Controller, имеют ряд недостатков:

  1. View и Controller имеют доступ ко всем глобальным переменным и параметрам экрана выбора.
  2. Обработка PBO и PAI в Controller требует получения состояния View (например получение выделенных строк ALV) или обновление View (например обновление таблицы ALV). В качестве решения данной проблемы нередко можно увидеть публичные атрибуты View, на которые воздействует Controller, или когда View имеет ссылку на Controller. Оба решения плохие, т.к. в первом случае нарушается инкапсуляция, а во втором Low Coupling.

MVVM в ABAP или MVA

Желая использовать преимущества MVVM в ABAP и сделать слои более независимыми я определил для себя следующий шаблон разработки.

image

Так как в чистом виде MVVM реализовать на ABAP нельзя, то ViewModel использовать не совсем корректно. Поэтому вместо ViewModel и Controller я использую Application.

Принцип разделения логики аналогичен принципу MVVM. View передает команды пользователя в Application, а Application воздействует на модель. Обратная связь при этом отсутствует.
Особенностью ABAP приложений является то, то представление может обновиться только после действий пользователя. Даже если какой-нибудь асинхронный процесс поменяет модель, то инициировать обновление представление он не сможет. Данная особенность позволяет ослабить связь модель-представление и делегировать функцию обновления представления самому представлению. Иными словами, представление само должно решать, когда надо обновить себя, а когда нет.

Концепция MVA

Реализация MVA основана на объектно-ориентированном подходе, где на каждый слой архитектуры будет реализован один или несколько классов. Каждый из слоев обладает рядом свойств.

Представление (View и IView):

  • MVA работает с абстракцией представления IView. Все классы View должны содержать реализацию IView.
  • IView содержит события, которые требуют взаимодействия с моделью
  • IView содержит контекст — ссылка на данные модели, которые необходимо отобразить пользователю
  • View может содержать бизнес-логику, которая не требует взаимодействия с моделью. Например, если требуется реализовать из ALV проваливание в карточку контрагента, то данная логика будет относиться к представлению.
  • View содержит GUI элементы в группе функций, которая связана с классом View.

Приложение (Application):

  • Выполняет роль связки представления и модели и является точкой входа в приложение.
  • Имеет критерии запуска — набор параметров, которые определяют с какими параметрами необходимо запустить приложение. Обычно это параметры селекционного экрана.
  • Критерии приложения состоят из критериев модели и представления. Например, если на селекционном экране требуется ввести дату проводки и указать флаг вывода отчета PDF или ALV, то дата проводки будет относиться к критериям модели, а флаг PDF и ALV к критериям представления.
  • В конструктор приложения передаются критерии запуска. Приложение создает модель и представление, подписывается на события представления, связывает контекст представления с моделью.

Модель (Model):

  • Содержит публичные атрибуты, которые необходимы представлению.
  • Содержит критерии расчета модели и метод инициализации.

Реализация MVA

Рассмотрим реализацию MVA на примере отчета по движению материалов. В качестве взаимодействия с моделью будет кнопка обновления данных.

Диаграмма классов будет выглядеть следующим образом.

Реализация MVVM в ABAP - 4

Model. Конструктор модели будет принимать на входи критерии выбора данных. Класс будет иметь методы инициализации и обновления данных, а также атрибут с данными для отображения.

Реализация MVVM в ABAP - 5

Реализация MVVM в ABAP - 6

Реализация MVVM в ABAP - 7

IView. Интерфейс представления содержит методы установки контекста, отображения представления, события и определение типов контекста.

Реализация MVVM в ABAP - 8

Реализация MVVM в ABAP - 9

Реализация MVVM в ABAP - 10

IView содержит в себе описание структуры контекста, причем поля структуры должны быть ссылочными

Реализация MVVM в ABAP - 11

View. Представление реализует интерфейс IView. Причем все события пользователя регистрирует класс View и вызывает только те события, которые нужно обработать приложению. В параметрах событий необходимо передать все данные, которые нужны от View (например, выделенные строки ALV).

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

Реализация MVVM в ABAP - 12

В данной реализации нам необходимо определение GUI статуса, для этого создадим ФМ и свяжем его с экземпляром CL_SALV_TABLE

Реализация MVVM в ABAP - 13

Важно что все UI события принимает View (в данном случае через ON_USER_COMMAND) и при необходимости View делает RAISE EVENT для Application. Этот подход делает View и Application более независимыми.

Application. Конструктор приложения принимает на вход критерии приложения (параметры экрана выбора) и создает экземпляры Model и View, подписывается на события View и связывает контекст View с Model. Конструктор — это единственное место где приложение знает о View. Application содержит метод RUN, который запускает программу. Запуск приложения можно сравнить с запуском транзакции с заранее определенными параметрами экрана. Это позволяет использовать ее из других программ без SUBMIT.

Реализация MVVM в ABAP - 14

Запуск Application. Теперь делаем программу, которая будет запускать приложение.

Реализация MVVM в ABAP - 15

Все, приложение готово. Можно смотреть результат.

Реализация MVVM в ABAP - 16

Бизнес-логика на стороне View. Обработку событий, которые не требуют обращения к модели и контроллеру, можно делать в самой View.

Например, если требуется реализовать открытие MM03 при двойном клике на MATNR, то обработку данной логики можно сделать на стороне View.

Реализация MVVM в ABAP - 17

На уровень View данная логика вынесена исходя из соображений: к модели не требуется обращаться за дополнительными данными; логика относится только к ALV, т.е. если бы была реализация View в виде Excel или PDF, то данное событие невозможно было бы обработать.

Литература

Design Patterns in ABAP Objects [1]
Паттерны для новичков: MVC vs MVP vs MVVM [4]
Архитектурные шаблоны в ABAP: MVC, MVP, MVVM, MVA [5]

Автор: Александр

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/mvvm/356243

Ссылки в тексте:

[1] Design Patterns in ABAP Objects: https://www.sap-press.com/design-patterns-in-abap-objects_4277/

[2] sapland.ru: https://sapland.ru/kb/articles/stats/mvc-ili-kak-pisati-otcheti-bistro-i-prosto.html

[3] blogs.sap.com: https://blogs.sap.com/2016/08/10/mvc-model-view-controller-framework-for-abap/

[4] Паттерны для новичков: MVC vs MVP vs MVVM: https://habr.com/ru/post/215605/

[5] Архитектурные шаблоны в ABAP: MVC, MVP, MVVM, MVA: http://abap4.ru/mvc-like-design-patterns-in-abap.html

[6] Источник: https://habr.com/ru/post/516208/?utm_source=habrahabr&utm_medium=rss&utm_campaign=516208