Комментарии по теме

«Ко­рре­кти­ро­вка таблиц базы данных с помощью ABAP»
Олег Точенюк:
Андрей а вам никто никогда не говорил, что обновлять таблицы базы данных SAP категорически запрещено, независимо от того чем обусловлены такие желания. Свои Z-таблицы, да сколько угодно, но......
«Тра­нза­кция SM02: сообщения в SAP системе»
Олег Башкатов:
С помощью ФМ TH_POPUP можно отправить сообщение конкретному пользователю :-)
«Способов до­ба­вле­ния текстовых полей в отчёты»
Олег Точенюк:
Написано хорошо, но яркий пример когда название статьи совсем не отражает изложенной в ней сути?! Пока читал все пытался понять где же тут стандартные отчеты SAP для которых будут "описаны способы...

База знаний

MVC или как писать отчеты быстро и просто

7832
15

Оглавление

Введение

Создание приложения

Model

View

Controller

Модули, активация и первый запуск

Алгоритм работы

Насколько тема актуальна?

Заключение

Введение

Привет, коллега!

Следующие несколько абзацев помогут тебе сэкономить время при разработке большинства видов отчетов на языке ABAP. Так же они помогут тебе разнести всю программную логику по отдельным блокам - классам. Для дальнейшего понимания материала тебе понадобятся всего лишь базовые знания объектно-ориентированного подхода к программированию.

Я уже чувствую, как в твоей голове летает долька сомнения и недоверия, но давай по порядку. Речь пойдет о так называемом шаблоне архитектуры или паттерне MVC (что такое шаблоны архитектуры более подробно можно прочитать здесь). А рассматривать их мы будем на примере создания классического отчета с использованием ALV-таблицы.

Мы разберем самый простой пример - отчет на основе ALV-таблицы, который будет показывать нам все единицы оборудования, созданные после заданной на экране даты.

Создание приложения

Я предлагаю сразу рассматривать архитектуру на живом примере, но для начала давайте посмотрим на рисунок ниже (Рис. 1). На нем схематично изображены составляющие части MVC.

Рис. 1. Схема взаимодействия компонентов MVC

Model, View и Controller (отсюда и MVC) - это те самые компоненты, которые нам необходимо реализовать в виде отдельных классов. Основной идеей такой архитектуры является разделение обработки данных, пользовательского интерфейса и управляющей логики на три отдельных компонента: модель, представление и контроллер. При таком разнесении логики модификация каждого компонента может осуществляться независимо.

Для чего нужен каждый из компонентов:

  • Модель (Model) предоставляет данные и реагирует на команды контроллера, изменяя свое состояние.
  • Представление (View) отвечает за отображение данных модели пользователю, реагируя на изменения модели.
  • Контроллер (Controller) интерпретирует действия пользователя, оповещая модель о необходимости изменений.

За счет разделения у нас появляются более широкие возможности повторного использования кода (наследование). Особенно это помогает, когда пользователь должен видеть те же самые данные в различных контекстах и/или с различных точек зрения. Это наиболее актуально в следующих ситуациях:

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

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

Model

Model (модель) - это некоторый объект, представляющий из себя данные. Например, полученный список единиц оборудования из таблицы EQUI.

Давайте сразу же его и реализуем в нашем приложении (Рис. 2).

Для описания каждого класса я советаю делать свой отдельный инклуд. Итак, создаем новый инклуд в нашей программе и описываем в нем класс lcl_model.

Рис. 2. Список единиц оборудования из таблицы EQUI

Мы только что описали класс, с помощью которого будет происходить получение данных по ЕО для вывода в ALV таблицу. В конструкторе мы запоминаем дату создания ЕО, начиная с которой будет происходить поиск. Далее в методе init_data получаем данные из БД. Эта логика выполнена в виде отдельного метода, потому что он нам еще понадобится в следующем уроке.

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

View

Переходим к реализации класса отображения на экране полученной объектом модели  информации - lcl_view. Так же, как и в предыдущем пункте, создаем для него отдельный инклуд (рис. 3).

Рис. 3. Реализация класса

Ограниченный доступ

Для прочтения полной версии статьи необходимо зайти как зарегистрированный пользователь.

Комментарии:

Олег Башкатов (Рейтинг: 7779) 01:05, 24 апреля 2017

у Вас в разработке по сути 2 view, независимых друг от друга:
1) это селекционный экран отчета
2) и экран ALV на базе класса cl_salv_table
и эти два view контролируются разными controller (1 - создается стандартно за кадром; 2 - создался Вами).
 
кроме того, Вы говорите
"данный шаблон отлично подходит (масштабируется) для отчетов с большим количеством всевозможных enjoysap control'ами с реализацией их взаимодействия.", а при этом используете упрощенный класс cl_salv_table.
почему?
09:48, 24 апреля 2017

Олег Точенюк (Рейтинг: 10291)

Ну это для упрощения наверное, чтобы не рисовать много кода. Тут же только принцип организации изложен вроде как.
15:35, 25 апреля 2017

Иван Тюменьев (Рейтинг: 397)

Это первая статья и она вводная. Не хотелось запихивать все и сразу. Пример использования нескольких контролов обязательно будет в дальнейшем.

Юрий Жуков (Рейтинг: 84) 09:11, 25 апреля 2017

Передавать таблицу в display не совсем правильно с точки зрения ООП, вроде. Например, появиться требование вывести кроме таблицы, ещё какую-нибудь заголовочную часть. Потребуется вносить изменения в контроллер, хотя изменилась только структура данных и её отображение, а управление осталось прежним.
15:39, 25 апреля 2017

Иван Тюменьев (Рейтинг: 397)

В данном случае передача таблицы в display скорее необходимость. Т.к. в конструктор передать changing параметр невозможно.
 
Вывод не только таблицы будет показан в дальнейшем.
 
"Не совсем правильно с точки зрения ООП" - хотелось бы немного аргументации...
16:47, 25 апреля 2017

Юрий Жуков (Рейтинг: 84)

Необходимости нет. По-хорошему во view должна быть ссылка на модель и view должна сама брать данные из модели. А из модели уж как угодно можно данные выдавать или как атрибут или через метод (зависит от того насколько надо абстрагироваться). Тогда и контроллер не будет зависеть от структуры модели. В контроллере должна быть только настройка связи между view и model.
 
Не совсем правильно, потому что такая передача нарушает инкапсуляцию внутренностей объекта модель, контроллер "знает" как устроена модель, хотя, по идее, ему должно быть всё равно, что внутри модели. Если конечно придерживаться концепции пассивной модели, то и передача через контроллер выглядит нормальной, так как вся бизнес логика всё равно будет сосредоточена в контроллере. А если делать контроллер по всем правилам, то в нём должна быть только логика управления связями между остальными объектами и маршрутизация сообщений в их обработчики. Для простого ALV отчета, это правда уже перебор.
14:48, 28 апреля 2017

Иван Тюменьев (Рейтинг: 397)

Если идти по первому пути, то мы получим высокую связность между объектами: вью будет знать с какой он работает моделью. Передавая данные модели через контроллер, мы убираем эту связь. Только контроллер продолжает знать, с какой моделью он работает. По хорошему, конечно, я должен был получить ссылку на таблицу модели в контроллере и передать ее уже вью. Но я не вижу смысла в таком финте: создавать get метод в модели, запомнить ссылку на таблицу в контроллере, потом ее передать дальше. В случае нескольких моделей это имеет смысл...
На счет нарушения инкапсуляции, согласен. К сожалению, до версии 7.40 очень громосткий код получается, если писать все по канонам. Но опять же, это один из примеров реализации, который каждый может доработать под себя.
09:23, 05 мая 2017

Юрий Жуков (Рейтинг: 84)

>> вью будет знать с какой он работает
>>моделью. Передавая данные модели через
>>контроллер, мы убираем эту связь.
 
Вью не будет знать с какой моделью оно работает, оно будет знать только что объект который ей передали как модель реализует интерфейс, который необходим для вью. А вот передавая данные средствами контроллера как раз таки и создается высокая связность. Появляется как минимум на одну связь больше - если меняется интерфейс модели, приходится менять и котроллер.

Евгений Лапшин (Рейтинг: 19) 13:07, 25 апреля 2017

1. Иван, разве обновление данных не должно происходить через контроллер (рис.1)?
2. Не описана обработка действий пользователя VIEW. Хочется видеть хотя бы самый простой пример.
15:51, 25 апреля 2017

Иван Тюменьев (Рейтинг: 397)

1) Существуют различные реализации паттерна MVC. В данном случае смысла в ручном обновлении нет, т.к. связь View с таблицей модели по ссылке. Обновятся данные в таблице - передавать их заново не придется.
2) Все будет, следите за новыми статьями! (;

Олег Точенюк (Рейтинг: 10291) 23:38, 28 апреля 2017

>>"Самое главное - это расположить инклуды с моделью и представлением до инклуда с контроллером"
 
А может проще написать в начале что-то типа:
CLASS: <имя> DEFINITION DEFERRED,
       <имя> DEFINITION DEFERRED,
       <имя> DEFINITION DEFERRED.
 
И тогда будет все равно как оно там дальше в инклудах находится.
14:59, 29 апреля 2017

Олег Башкатов (Рейтинг: 7779)

если на то пошло, то можно использовать OOP подход при создании транзакции, и забыть про include как таковой и про их расположение в том числе :-)
 
пример описан здесь:
sapland.ru/blogs/phaizullin
13:17, 16 июня 2017

Рамиль Тен (Рейтинг: 10)

Не понятно зачем реализовать данный функционал в глобальном классе. Это как то излишне. Кроме того сомнительно использование концепции статьи в больших разработках.
Легче реализовать функционал по отрисовке ALV и отработке событий в одном классе. А в конструктор передавать контейнер и набор входных данных.

Михаил Короченков (Рейтинг: 75) 15:04, 11 октября 2017

Иван, вы c первой статьи учите не правильному стилю MVC (в ABAP-е в частности) скорее всего потому что сами только пробуете данный подход и не набили на нем руку достаточно.
А именно: представления (View) как я думаю вы знаете бывают тонкие и толстые (которые лишь отображают данные и  которые кроме отображения производят над ними действия). При использовании патерна MVC в ABAPe используется почти всегда концепция толстого представления, даже ваше простое view является таковым. Исходя из такого подхода обязательно нужно хранить данные выводимые(обрабатываемые) представлением в самом представлении (хранить в атрибутах,конечно же нужно их туда передавать(как именно разговор другой). Только так достигается независимость View от Model( для примера с ALV-view очень часто нужна структура данных во вью отличающееся от модели, при этом ссылка никакая вам не поможет, да и ссылка это тоже не корректный подход толстого представления).

Михаил Короченков (Рейтинг: 75) 15:05, 11 октября 2017

Иван, вы c первой статьи учите не правильному стилю MVC (в ABAP-е в частности) скорее всего потому что сами только пробуете данный подход и не набили на нем руку достаточно.
А именно: представления (View) как я думаю вы знаете бывают тонкие и толстые (которые лишь отображают данные и  которые кроме отображения производят над ними действия). При использовании патерна MVC в ABAPe используется почти всегда концепция толстого представления, даже ваше простое view является таковым. Исходя из такого подхода обязательно нужно хранить данные выводимые(обрабатываемые) представлением в самом представлении (хранить в атрибутах,конечно же нужно их туда передавать(как именно разговор другой). Только так достигается независимость View от Model( для примера с ALV-view очень часто нужна структура данных во вью отличающееся от модели, при этом ссылка никакая вам не поможет, да и ссылка это тоже не корректный подход толстого представления).

Любое воспроизведение запрещено.
Копирайт © «Издательство ООО «Эксперт РП»