Ansicht
Dokumentation

ABENSTATIC_CLASS_SINGLETON_GUIDL - STATIC CLASS SINGLETON GUIDL

ABENSTATIC_CLASS_SINGLETON_GUIDL - STATIC CLASS SINGLETON GUIDL

Fill RESBD Structure from EBP Component Structure   Vendor Master (General Section)  
Diese Dokumentation steht unter dem Copyright der SAP AG.
SAP E-Book

Statische Klassen und Singletons

Die Klassen von ABAP Objects unterstützen zwei Arten von Komponenten:

  • Instanzkomponenten, das heißt Instanzattribute, Instanzereignisse und Instanzmethoden. Die Instanzkomponenten einer Klasse sind nur über Instanzen der Klasse (Objekte) adressierbar.
  • Statische Komponenten, das heißt statische Attribute, statische Ereignisse und statische Methoden. Die statischen Komponenten einer Klasse sind nicht nur über ein Objekt, sondern auch über den Namen der Klasse adressierbar und damit unabhängig von einer Instanz der Klasse verwendbar.

Eine Klasse, die ausschließlich statische Komponenten und keine Instanzkomponenten enthält, bezeichnet man als statische Klasse. Eine globale statische Klasse wird bei ihrer Verwendung mit ihrem Class-Pool einmal in die aktuelle interne Sitzung geladen und kann wie jedes ABAP-Programm nicht explizit aus diesem gelöscht werden. Die statischen (über CLASS-METHODS deklarierten) Methoden einer Klasse können in Unterklassen nicht redefiniert werden.

Ein Singleton ist ein Entwurfsmuster, bei dem die Klasse die Verantwortung zur Objekterzeugung selbst übernimmt und sicherstellt, dass stets nur genau ein Objekt pro interner Sitzung existiert, das sie den Verwendern zur Verfügung stellt.

Keine statischen Klassen verwenden

Verwenden Sie vorzugsweise Objekte anstatt statischer Klassen. Falls keine Mehrfachinstanzierung gewünscht ist, können Singletons benutzt werden.

Insbesondere beim Fehlen eines echten objektorientierten Designs, das beispielsweise die Mehrfachinstanzierung von Klassen ausnützen würde, entstehen bei der Verwendung von ABAP Objects häufig Klassen, die lediglich statische Methoden (deklariert über CLASS-METHODS) enthalten. Diese Methoden werden dann als einfache Prozeduren verwendet. Aber auch wenn eine Mehrfachinstanzierung explizit nicht gewünscht ist, ist eine Objekterzeugung aus den im Folgenden genannten Gründen der Verwendung von statischen Klassen vorzuziehen, wobei zur Vermeidung der Mehrfachinstanzierung das Singleton-Entwurfsmuster verwendet werden kann:

  • Die explizite Objekterzeugung ist das A und O jeder objektorientierten Programmierung. Statische Klassen werden dagegen bei der ersten Verwendung implizit geladen, und der zugehörige statische Konstruktor, soweit vorhanden, wird ausgeführt. Sie bleiben so lange im Speicher bestehen, wie die aktuelle interne Sitzung existiert. Daher hat man bei statischen Klassen keine echte Kontrolle über den Zeitpunkt der Initialisierung und auch keinerlei Möglichkeit, den durch die Attribute belegten Speicher wieder freizugeben, sobald die Klassenfunktionalität nicht mehr benötigt wird.
  • Ein weiteres wichtiges Argument, das gegen die Verwendung statischer Klassen spricht, ist die eingeschränkte Funktionalität des statischen Konstruktors im Vergleich zu einem Instanzkonstruktor. Ein statischer Konstruktor hat keine Parameterschnittstelle und kann keine Ausnahmen propagieren, weshalb auf eine Fehlersituation im statischen Konstruktor nicht immer angemessen reagiert werden kann und diese im Extremfall zu einem Laufzeitfehler führt. Die Ausnahmen eines Instanzkonstruktors können dagegen behandelt werden.
  • Durch die Verwendung statischer Klassen verbaut man sich die Möglichkeiten der Polymorphie, welche die objektorientierte Programmierung eigentlich bietet. Zum einen können statische Methoden nicht redefiniert werden, zum anderen entfällt der Zugriff über Referenzvariablen, dem anderen Standbein der Polymorphie. Es ist jedoch günstig, sich die Option der Polymorphie offenzuhalten:
  • Auch wenn zunächst nicht geplant ist, das Verhalten einer Methode später einmal durch Vererbung und Redefinition zu überschreiben, stellt sich dieser Wunsch häufig im Laufe der Weiterentwicklung ein.

  • Zur Realisierung von Modultests mit ABAP Unit ist es häufig unumgänglich, das Verhalten bestimmter Methoden zu redefinieren, um problematische Abhängigkeiten aufzulösen.

Um sich die Möglichkeit zur Redefinition offenzuhalten, sollten anstelle von statischen Methoden stets instanzgebundene Methoden verwendet werden.

Das Besorgen eines Singleton-Objektes und der anschließende Aufruf einer Instanzmethode können sehr kompakt in Form eines verketteten Methodenaufrufs ausgedrückt werden:

cl_singleton=>get_instance( )->do_something( ).

Durch den Wegfall einer zusätzlichen Objektreferenzvariablen und eines zusätzlichen Factory-Aufrufs fallen damit auch etwaige ästhetische Nachteile bei der Verwendung des Singleton-Entwurfsmusters weg.

Ausnahme

Klassen, die lediglich triviale Funktionalität abdecken, können weiterhin als statische Klassen realisiert werden. Hierbei ist aber genau abzuwägen, ob nicht doch einer der oben genannten Punkte zu tragen kommen könnte. Ein Indikator kann hier die Notwendigkeit für einen Klassenkonstruktor sein. Sobald eine statische Klasse einen nicht-trivialen Klassenkonstruktor bräuchte, um die gewünschte Funktionalität abzudecken, sollten stattdessen Objekte zum Einsatz kommen.

Folgender Quelltext zeigt eine statische Klasse mit ausschließlich statischen Methoden sowie die Verwendung einer dieser Methoden. Aus dem Quelltext ist im Allgemeinen nicht ohne Weiteres ersichtlich, ob der Methodenaufruf auch zum Aufruf des statischen Konstruktors führt oder ob dieser bereits zu einem früheren Zeitpunkt, beispielsweise infolge eines einfachen Attributzugriffs, erfolgt ist.

CLASS static_class DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: class_constructor,
                   meth1,
                   meth2,
                   ...
ENDCLASS.
...
static_class=>meth1( ).
...

Folgender Quelltext zeigt eine Implementierung des Singleton-Entwurfsmusters, bei dem eine statische Methode den Zugriff auf das einzige Objekt der Klasse ermöglicht.

CLASS singleton_class DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS get_instance
    RETURNING VALUE(r_instance) TYPE REF TO singleton_class
    RAISING cx_some_failure.
  METHODS constructor
    RAISING cx_some_failure.
  METHODS: meth1,
           meth2.
           ...
  PRIVATE SECTION.
    CLASS-DATA instance TYPE REF TO singleton_class.
ENDCLASS.

CLASS singleton_class IMPLEMENTATION.
  METHOD get_instance.
    IF instance IS NOT BOUND.
      CREATE OBJECT instance.
    ENDIF.
    r_instance = instance.
  ENDMETHOD.
  ...
ENDCLASS.

...
  TRY.
     singleton_class=>get_instance( )->meth1( ).
   CATCH cx_some_failure.
     ...
  ENDTRY.

In obigem Beispiel dient die Methode get_instance dazu, die Objektreferenz auf das beim ersten Aufruf erzeugte Objekt zurückzuliefern. Damit verstößt dieses Beispiel zunächst scheinbar gegen Regel Modularisieren anstatt zu atomisieren nach der in ABAP keine Methoden angelegt werden sollen, die lediglich den Wert eines Attributes zurückliefern. Dieser Einwand ist hier jedoch unberechtigt, da die Hauptaufgabe der Methode get_instance darin besteht, den Zeitpunkt der Objekterzeugung unter die Kontrolle des Objektverwenders zu stellen. Nur auf diese Weise kann der Verwender auf etwaige Ausnahmesituationen während der Objekterzeugung in gewohnter Weise reagieren.

In Sonderfällen, in denen die Objekterzeugung unparametrisiert erfolgt und stets erfolgreich ist, kann auf eine get_instance-Methode verzichtet und die Objektreferenz über ein READ-ONLY-Attribut veröffentlicht werden. Da dann die Objekterzeugung innerhalb des statischen Konstruktors erfolgt, ist dieser Ansatz allerdings weiterhin mit einigen der beschriebenen Probleme statischer Klassen behaftet.






BAL_S_LOG - Application Log: Log header data   General Material Data  
Diese Dokumentation steht unter dem Copyright der SAP AG.

Length: 9939 Date: 20240523 Time: 085749     sap01-206 ( 165 ms )