This is a test message to test the length of the message box.
Login
ABAP OO Methodenschnittstelle
Erstellt von Software-Heroes

ABAP OO - Methodenschnittstellen

476

Wie sollten Methodenschnittstellen aktuell aussehen und wie erreichst du diesen Zustand? In diesem Artikel werden wir die Frage klären.

Werbung

Wie sollte in der heutigen Zeit eigentlich eine Methodenschnittstelle aussehen und was bringen dir eigentlich kleine Schnittstellen bei deiner täglichen Arbeit? Diese Frage wollen wir uns einmal genauer anschauen und dabei auch die Vergangenheit in SAP etwas genauer beleuchten.

 

Vergangenheit

In der Vergangenheit wurden Schnittstellen recht einfach definiert und für jeden Parameter gab es eine eigene Variable. Bei RFC Funktionsbausteinen macht dies auch Sinn, da komplexe Datentypen von Außen schwer ansprechbar sind. Ebenso existieren im System BAPIs in verschiedenen Ausprägungen und Komplexitäten. Wenn du in der letzten Zeit mal einen in dein Coding implementiert hast, wirst du wissen wovon wir reden, die Schnittstellen sind meist nicht sehr übersichtlich.

 

Herausforderung

In der objektorientierten Programmierung sind solche "Monsterschnittstellen" nicht sehr praktikabel, da sie sich schlecht in ein IF Statement packen lassen und die Methoden nicht besonders klein machen. Stell dir deshalb einfach mal das folgende Szenario vor:

  • Deine Klasse muss erweitert werden und du möchtest einen oder mehrere neue Parameter über die Main Methode in die Klasse einschleusen, um im Inneren damit zu arbeiten.
  • Deine Schnittstelle nutzt einzelne Parameter, damit du die Datenübergabe ordentlich regeln kannst.

 

Die Klasse könnte nun wie folgt aussehen und implementiert zur Demonstration nur eine einfache Logik, bei der wir die Parameter an andere Methoden weitergeben, um sie dort zu verwenden.

CLASS zcl_interface_not_clean DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    TYPES:
      tt_r_bukrs TYPE RANGE OF t001-bukrs,
      tt_r_waers TYPE RANGE OF t001-waers,

      tt_t001    TYPE STANDARD TABLE OF t001 WITH EMPTY KEY.

    METHODS:
      main
        IMPORTING
          it_r_bukrs TYPE tt_r_bukrs
          it_r_waers TYPE tt_r_waers
          id_butxt   TYPE t001-butxt
          id_test    TYPE abap_bool.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      select_data
        IMPORTING
          it_r_bukrs TYPE tt_r_bukrs
          it_r_waers TYPE tt_r_waers
        EXPORTING
          et_t001    TYPE tt_t001,

      update_data
        IMPORTING
          it_t001  TYPE tt_t001
          id_butxt TYPE t001-butxt
          id_test  TYPE abap_bool.
ENDCLASS.


CLASS zcl_interface_not_clean IMPLEMENTATION.
  METHOD main.
    select_data(
      EXPORTING
        it_r_bukrs = it_r_bukrs
        it_r_waers = it_r_waers
      IMPORTING
        et_t001    = DATA(lt_t001)
    ).

    update_data(
      EXPORTING
        it_t001  = lt_t001
        id_butxt = id_butxt
        id_test  = id_test
    ).
  ENDMETHOD.


  METHOD select_data.
    SELECT *
      FROM t001
      WHERE bukrs IN @it_r_bukrs
        AND waers IN @it_r_waers
      INTO TABLE @et_t001.
  ENDMETHOD.


  METHOD update_data.
    DATA(lt_t001) = it_t001.

    LOOP AT lt_t001 REFERENCE INTO DATA(lr_t001).
      lr_t001->butxt = id_butxt.
    ENDLOOP.

    IF id_test = abap_false.
      UPDATE t001 FROM TABLE lt_t001.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

Wollen wir zum Beispiel eine neue Range zur Abfrage der Daten von der Tabelle T001 implementieren, müssen wir einige Stellen anpassen, was mehr Zeit dauert und aufwändiger ist.

 

Lösung

Dazu gibt es auch im Repository von Clean ABAP einen entsprechenden Eintrag. Es wird ebenso empfohlen einen Importing und einen Returning Parameter zu verwenden, da sich die Methoden so am Einfachsten nutzen lassen. Die Herausforderung liegt nun dabei sein Schnittstellen entsprechend aufzubauen. Hier stehen dir im Grunde zwei bewährte Methoden zur Verfügung:

  • Verwendung einer Struktur mit den entsprechenden Merkmalen auf der Strukturebene
  • Verwendung eines Objekts als Datencontainer

 

Beide Methoden haben auch ihren Charme, wir empfehlen aber das Objekt, da du damit am Flexibelsten bist und weitere Logik, sowie Validierungen direkt an die Daten hängen kannst. Außerdem ist ein Objekt änderbar, was bei einer Struktur nicht möglich ist, die nur als Importing übergeben wird.

Dazu legen wir im nächsten Schritt eine Konfiguration an, der Einfachheit verwenden wir kein Interface, sondern bauen direkt die Klasse auf. Wie wir dir in ABAP Unit erklärt haben, sollte aber zur leichteren Testbarkeit ein Interface verwendet werden:

CLASS zcl_test_config DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    TYPES:
      tt_r_bukrs TYPE RANGE OF t001-bukrs,
      tt_r_waers TYPE RANGE OF t001-waers.

    DATA:
      mt_r_bukrs TYPE tt_r_bukrs,
      mt_r_waers TYPE tt_r_waers,
      md_butxt   TYPE t001-butxt,
      md_test    TYPE abap_bool.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_test_config IMPLEMENTATION.
ENDCLASS.

 

An dieser Stelle bauen wir nun unsere Ausgangsklasse einmal um und verwenden das neue Konfigurationsobjekt. Bei der Übergabe wird die Schnittstelle schon einmal viel kleiner und ist nun leicht erweiterbar.

CLASS zcl_interface_clean DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    TYPES:
      tt_t001 TYPE STANDARD TABLE OF t001 WITH EMPTY KEY.

    METHODS:
      main
        IMPORTING
          io_config TYPE REF TO zcl_test_config.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      select_data
        IMPORTING
                  io_config      TYPE REF TO zcl_test_config
        RETURNING VALUE(rt_t001) TYPE tt_t001,

      update_data
        IMPORTING
          it_t001   TYPE tt_t001
          io_config TYPE REF TO zcl_test_config.
ENDCLASS.


CLASS zcl_interface_clean IMPLEMENTATION.
  METHOD main.
    DATA(lt_t001) = select_data( io_config ).

    update_data( it_t001  = lt_t001 io_config = io_config ).
  ENDMETHOD.


  METHOD select_data.
    SELECT *
      FROM t001
      WHERE bukrs IN @io_config->mt_r_bukrs
        AND waers IN @io_config->mt_r_waers
      INTO TABLE @rt_t001.
  ENDMETHOD.


  METHOD update_data.
    DATA(lt_t001) = it_t001.

    LOOP AT lt_t001 REFERENCE INTO DATA(lr_t001).
      lr_t001->butxt = io_config->md_butxt.
    ENDLOOP.

    IF io_config->md_test = abap_false.
      UPDATE t001 FROM TABLE lt_t001.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

Fazit

Mit der entsprechenden Technik und einer gewissen Voraussicht sollte es möglich sein, die Schnittstellen sehr klein zu halten und deine Objekte in Zukunft offen für Erweiterungen zu lassen, ohne die Schnittstellen komplett umbauen und erweitern zu müssen.


Enthaltene Themen:
OOABAP OOMethodenschnittstelle
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


ABAP Tools - Tool Bridge konfigurieren

Kategorie - ABAP

Schauen wir uns einmal an, was die Tool Bridge in den ABAP Development Tools ist und wie du sie ganz einfach konfigurieren kannst.

28.05.2024

ABAP OO - Methodenparameter

Kategorie - ABAP

In diesem Artikel einmal die Grundlagen der Parameter in Methoden und wie sich diese bei verschiedenen Typen verhalten.

09.04.2024

ABAP Tools - Arbeiten mit Eclipse (Objekt starten)

Kategorie - ABAP

In diesem Artikel ein kleiner Tipp zum direkten Start von Objekten, ohne den Umweg über die Anzeige des Objekts.

19.03.2024

ABAP Tools - Arbeiten mit Eclipse (Tabellenanlage)

Kategorie - ABAP

In diesem Artikel gehen wir den Flow zur Anlage von Tabellen in den ABAP Development Tools durch und wie du ihn einfach gestalten kannst.

22.12.2023

ABAP Tools - Arbeiten mit Eclipse (Quellcodevergleich)

Kategorie - ABAP

Hier schauen wir uns an, wie wir mit den ABAP Development Tools Quellcode vergleichen können, einmal über Systeme hinweg und einmal die letzten Versionen.

01.12.2023