- При разработке ПО необходимо придерживаться основных принципов ООП: инкапсуляция, полиморфизм и наследование, а также SOLID, DRY, KISS и YAGNI.
- Для решения типовых задач необходимо использовать шаблоны проектирования.
- Отчеты с экранной логикой рекомендуется реализовывать с помощью паттерна MVC (и ему подобных - MVP, MVVM).
- Статические методы используются только в крайнем и обоснованном случае. Например, в некоторых паттернах проектирования (singleton) или утилитных классах (10 раз подумать, нужен ли он такой).
- Разбивать ПО на логические части с помощью инклудов. Например, описание селекционного экрана должна лежать в одном инклуде, его логика - в другом. Логика получения данных, например, тоже должна лежать отдельно от логики выгрузки данных или их отображения на экран.
- Не оставлять в программе закомментированных кусков старого кода. SAP поддерживает версионность и старые части кода всегда можно найти в соответствующей версии ПО.
- Не оставлять комментарии, обозначающие кто и когда добавил или изменил код. Это и так можно узнать из версии ПО.
- Для передачи значений через память (EXPORT TO MEMORY, IMPORT FROM MEMORY) объявить глобальный класс с константой названия и делать импорт/экспорт через него. Это облегчит поиск всех мест использования.
- Для ведения отдельных значений и диапазонов констант, а также признаков активации необходимо либо использовать тр-цию STVARV, либо разработать надстройку для ведения таблицы TVARV.
- В тексте главной программы должны быть дополнительно выделены основные события отчета: INITIALIZATION, START-OF-SELECTION, AT SELECTION-SCREEN и т.п.
- Использование оператора BREAK-POINT без указания ID активации и макроса BREAK USER_ID запрещено. Разрешается использование операторов BREAK-POINT с указанием ID активации, ASSERT - с указанием ID активации. Данные ID активации могут быть созданы с помощью тр-ции SAAB.
- Использование DBC (Batch Input) допустимо только в случае отсутствия стандартных BAPI.
- В расширениях должны быть только вызовы подпрограмм или методов какого-либо собственного класса, где реализованы все необходимые изменения и/или проверки, требующиеся в расширении.
- Не использовать конструкцию SELECT…END SELECT, кроме случая с UP TO 1 ROWS - аналог SELECT SINGLE, но с возможностью использования ORDER BY.
- Стараться не использовать операции неравенства (<> и NE) в условиях WHERE.
- Стараться не использовать операцию LIKE.
- Рекомендуется не выбирать «лишние» записи, которые будут отфильтрованы на уровне сервера приложений.
- Не использовать SELECT * (за исключением, когда указано INTO CORRESPONDING FIELDS OF), выбирать только необходимые поля из таблицы БД.
- Вместо SELECT в цикле LOOP…ENDLOOP использовать SELECT FOR ALL ENTRIES.
- Перед использованием SELECT FOR ALL ENTRIES желательно отсортировать внутреннюю таблицу и удалить из нее дубликаты, затем обязательно проверить, что в таблице осталась хотя бы одна запись.
- Использовать функции агрегирования (COUNT, MIN, MAX, SUM, AVG) вместо того, чтобы алгоритмически из реализовывать на уровне сервера приложений. Не использовать функции агрегирования в циклах.
- Операции модификации (INSERT, UPDATE, DELETE) следует выполнять над большим объемом данных, а не над единичными записями.
- Для проверки наличия записи в таблице БД использовать SELECT SINGLE или SELECT UP TO 1 ROWS.
- Если нет явной необходимости, то сортировку выбранных данных следует проводить на стороне сервера приложений.
- Для поиска данных указывать, где это возможно, все поля из используемого при поиске индекса (первичного или вторичного).
- По возможности при поиске данных из нескольких таблиц БД использовать JOIN, а не разбивать выборки на несколько отдельных.
- Запрещается создание объектов блокировок, блокирующих все записи таблицы.
- Оптимальные приемы работы с запросами SQL можно посмотреть, нажав на кнопку «Советы» первого экрана тр.SE30.
- Не использовать таблицы с заголовком, т.е. не использовать при объявления таблицы ключевые слова WITH HEADER LINE и OCCURS n.
- Не использовать отдельно объявленные структуры для чтения, изменения и добавления записей во внутреннюю таблицу, если это возможно. Вместо этого необходимо использовать FIELD SYMBOLS.
- Для ускорения поиска записи во внутренней таблице типа STANDARD TABLE в операторе READ можно использовать бинарный поиск (ключевые слова - BY BINARY SEARCH), но при этом таблица должна быть отсортирована по полю (полям) поиска. В SORTED TABLE бинарный поиск включается автоматически.
- Оптимальные приемы работы с внутренними таблицами можно посмотреть, нажав на кнопку «Советы» первого экрана тр.SE30.
- При большом количестве условий для одной и той же переменной или для одного и того же значения для разных переменных рекомендуется использовать оператор CASE…WHEN, вместо IF…ELSEIF.
- Не использовать в ПО явно заданные проверки на системную переменную SY-UNAME (например, IF sy-uname EQ ‘IVANOV_AA’).
- Минимизировать использование глобальных переменных, заменив их на локальные, и передавать их как аргументы в подпрограммы или методы. Прямое использование глобальных переменных в подпрограммах запрещается.
- Разбивать программный код на логические блоки, оформленные в подпрограммы или методы.
- Объявлять локальные и глобальные переменные и типы на уровне логического блока, в котором они используются (даже если логический блок оформлен в отдельную подпрограмму/метод), а не в начале программы/подпрограммы/метода.
- Обязательна обработка ситуаций-исключений при вызове функциональных модулей и методов классов.
- Обязательна обработка классов-исключений при вызове методов классов.
- Не использовать параметры TABLES в функциональных модулях.
- Не использовать параметры TABLES в подпрограммах.
- При расширении стандартных структур или таблиц именовать поля ZZ*.
- В PAI и PBO модулях описывать только логику обработки экранов, логику обработки данных необходимо прописывать в отдельных процедурах и методах.
- Запрещено комментировать код с помощью оператора "IF 1 NE 1...ENDIF." или "IF 1 EQ 2...ENDIF." или т.п., кроме случая, когда происходит неявная передача сообщения без его вызовы с помощью команды MESSAGE.
- Удалять (не оставлять закомментированным) старый код в новой версии программы. SAP поддерживает систему версионности и при необходимости старые куски кода всегда можно найти в предыдущих версиях ПО.
- При неявном вызове сообщения, например, при передаче в таблицу сообщений, для упрощения поиска места возникновения необходимо произвести явный вызов сообщения с помощью команды MESSAGE, но заключить данный вызов в оператор IF с условием 1 NE 1 или 1 EQ 2.
- Соблюдать иерархию отступов при вложенности циклов и условных операторов.
- При написании кода обязательно использование "Структурной печати".
- Не допускается запись нескольких операторов или условий в одной строке.
- Не допускается реализация логики в макросах DEFINE...END-OF-DEFINITION. Допускаются только линейные операции.
- Обязательно комментирование ключевых мест программного кода.
- При работе с внутренними таблицами с помощью FIELD-SYMBOL обязательно проверять успешность присвоения ссылки по "SY-SUBRC" или "IS ASSIGNED".
- Отчет должен содержать проверку полномочий на просмотр данных, определенных по параметрам экрана выбора.
- Избегать неявных commit'ов в BADI и OpenFI. Неявные commit'ы вызываются в следующих случаях:
- смена SAP экрана;
- вызов диалогового сообщения;
- оператор Wait прерван рабочим процессом;
- синхронный или асинхронный вызов RFC функции (исключение qRFC, tRFC, bgRFC);
- при вызове транзакции CALL TRANSACTION, LEAVE TO TRANSACTION или программы через SUBMIT.