* Einfache Klasse für Demo einer Factory-Klasse
* ist nicht über den Kontruktor von außen instanziierbar (CREATE PRIVATE), kann nur sich selbst instanziieren
* von lcl_factorydemo kann nicht geerbt werden (FINAL)
CLASS lcl_factorydemo DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
* statische Factory-Methode, übernimmt die Funktion des Konstruktors mit einigen organisatorischen Verbesserungen
CLASS-METHODS:
factory
IMPORTING
i_object_name TYPE string
RETURNING VALUE(ro_instance) TYPE REF TO lcl_factorydemo.
* statische Methode, zeigt die interne sortierte Objektliste
CLASS-METHODS:
get_object_list.
* Instanzmethode, gibt Objektnamen
METHODS:
get_name
RETURNING VALUE(rv_object_name) TYPE string.
PRIVATE SECTION.
* eigener Listtyp zur Verwaltung der internen Objektreferenzen
* über "name" können die Objektreferenzen gesucht werden
TYPES: BEGIN OF ty_instances,
name TYPE string,
o_instance TYPE REF TO lcl_factorydemo,
END OF ty_instances.
* sortierte Liste zur Verwaltung der Objektreferenzen, Primärschlüssel ist "name"
CLASS-DATA: git_instances TYPE SORTED TABLE OF ty_instances WITH UNIQUE KEY name.
* Instanzvariable, speichert Objektnamen
DATA: gv_object_name TYPE string.
* versteckter Instanzkonstruktor, ist von außerhalb der Klasse nicht aufrufbar (CREATE PRIVATE)
METHODS:
constructor
IMPORTING
i_object_name TYPE string.
ENDCLASS.
CLASS lcl_factorydemo IMPLEMENTATION.
* versteckter Instanzkonstruktor, ist von außerhalb der Klasse nicht aufrufbar (CREATE PRIVATE)
METHOD constructor.
gv_object_name = i_object_name.
ENDMETHOD.
* statische Factory-Methode
METHOD factory.
TRY.
* Instanz über den Namen suchen, wenn nicht vorhanden wird eine Exception CX_SY_ITAB_LINE_NOT_FOUND geworfen
ro_instance = git_instances[ name = i_object_name ]-o_instance.
CATCH cx_sy_itab_line_not_found.
* wenn also das Objekt nicht vorhanden ist, dann neues erzeugen
ro_instance = NEW #( i_object_name ).
* und in die iTab eintragen, wird automatisch anhand des Namens einsortiert
INSERT VALUE #( name = i_object_name
o_instance = ro_instance ) INTO TABLE git_instances.
ENDTRY.
ENDMETHOD.
* Instanzmethode, gibt Objektnamen
METHOD get_name.
rv_object_name = gv_object_name.
ENDMETHOD.
* statische Methode, zeigt die interne sortierte Objektliste
METHOD get_object_list.
LOOP AT git_instances ASSIGNING FIELD-SYMBOL(<fs_inst>).
WRITE: / <fs_inst>-name.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
* Drei Objekte per Factory-Methode erzeugen
* die ersten zwei Objekte werden erzeugt, da die Namen noch nicht
* in der internen Liste vorhanden sind
* die Objekte werden automatisch nach Namen sortiert (SORTED TABLE)
DATA(o_ref1) = lcl_factorydemo=>factory( i_object_name = 'OBJ_2' ).
WRITE: / o_ref1->get_name( ).
* Beispiel für Methodenverkettung (Method-Chaining)
WRITE: / lcl_factorydemo=>factory( i_object_name = 'OBJ_1' )->get_name( ).
* das dritte Objekt wird nicht erzeugt, da schon ein Objekt mit dem gleichen Namen existiert
* daher wird nur die Referenz auf das namensgleiche Objekt zurückgegeben
DATA(o_ref3) = lcl_factorydemo=>factory( i_object_name = 'OBJ_1' ).
WRITE: / o_ref3->get_name( ).
ULINE.
* sortierte Objektliste ausgeben -> nur zwei Objekte
* mit unterschiedlichen Namen werden angezeigt
lcl_factorydemo=>get_object_list( ).