Aufgabe

In dieser Aufgabe wird eine neue Klasse für einen Würfel angelegt. Dieser wird "verkapselt", so dass die Daten nach außen geschützt sind. Der einzige Zugang ist eine Methode ROLL, die das eigentliche würfeln implementiert.
Es wird ein Würfelspiel über 10 Runden mit 5 Würfeln simuliert und die Ergebnisse in die Console geschrieben.

Vorgehensweise

Klasse und Attribute

  • Klasse ZCL_BC_AOO_##_DIE_ENC anlegen mit Beschreibung Brandeis Training: ABAP Objects - Würfel - Gekapselt ##
  • Die Variablen MV_ID und MV_DESC vom Typ STRING in der PROTECTED SECTION anlegen
Code Snippet Attribute
    data mv_id type string.
    data mv_desc type string.

Constructor und Methoden

  • Einen CONSTRUCTOR mit Parametern und eine Methode ROLL mit einem RETURNING Parameter in der PUBLIC SECTION in der DEFINITION definieren
Code Snippet Methodendefinition
    METHODS constructor
        IMPORTING
            iv_id type string
            iv_description type string optional.

    METHODS roll RETURNING VALUE(rv_number) type i.
  • Mit Quickfix beide Methoden anlegen lassen und die Implementierung übertragen
Code Snippet Methodendefinition
  METHOD roll.
    return ZCL_BC_AOO_DICE_GAME_HELPER=>create(  )->random_get_integer( min = 1 max = 6 ).
  ENDMETHOD.

  METHOD constructor.
    mv_id   = iv_id.
    mv_desc = cond #( when iv_description is NOT INITIAL
                      then iv_description
                      else |Würfel { mv_id }| ).
  ENDMETHOD.
  • mit Pretty-Printer Code formatieren und aktivieren

Test

Zum Testen das persönliche Testtool ZCL_BC_AOO_##_TESTTOOL_BEC mit der Teilnehmernummer aufrufen.
Die Methodennamen für diese Übung heißen:

  • run_enc für den Einzeltest
  • run_enc_all für einen Test gegen andere Teilnehmer

Dazu muss die zu testende Methode entweder in die main-Methode mit aufgenommen oder über den Debugger die Variable lv_method auf die entsprechene Methode gesetzt werden.
Die Ausgabe der Console prüfen. Die Würfelergebnisse der 10 Runden mit 5 Würfeln werden hier angezeigt. Im Multiplayer Game spielen alle Spieler nacheinander.

Tipp: Vor dem Start des Tests einmal die Console löschen.

Lösung

Lösung
CLASS zcl_bc_aoo_##_die_enc DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS constructor
        IMPORTING
            iv_id type string
            iv_description type string optional.
    methods roll RETURNING VALUE(rv_number) type i.

  PROTECTED SECTION.
    data mv_id type string.
    data mv_desc type string.

  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_bc_aoo_##_die_enc IMPLEMENTATION.
  METHOD roll.
    return ZCL_BC_AOO_DICE_GAME_HELPER=>create(  )->random_get_integer( min = 1 max = 6 ).
  ENDMETHOD.

  METHOD constructor.
    mv_id   = iv_id.
    mv_desc = cond #( when iv_description is NOT INITIAL
                      then iv_description
                      else |Würfel { mv_id }| ).
  ENDMETHOD.
ENDCLASS.

Zusatzaufgaben

  1. Etwas mit dem Debugger üben und vor allem in objektorientierten Aufrufen klarkommen
  2. Tipp: Breakpoint in Methode ROLL und von dort tiefer rein oder auch raus debuggen: Tasten F5-F8 üben
  3. Im Debugger die erzeugten Variablen der Objektinstanz beobachten und auch die als Zwischenspeicher verwendete Tabelle prüfen
  4. Bestätigen, dass wirklich alle Instanzen eigene Datenbereiche haben (MV_ID und MV_DESC sind eindeutig)
  5. Prüfen, ob man mit dem Debugger den gewürfelten Wert der Methode ROLL anpassen kann. Ggf. mal einen ungültigen Wert '7' setzen.

Weitere Hinweise

Im Coding werden einige Entwurfsmuster und moderne ABAP Syntax verwendet:

  1. Die Methode ROLL ruft über eine statische sogenannte Factory-Methode "CREATE" eine API auf, die eine Instanz auf einen Zufallsgenerator zurückliefert
  2. Hier kann man schön sehen, dass mehrer Methoden "in Reihe" aufgerufen werden (erkennbar an ( )).
  3. Der Aufruf von statischen Methoden kann erkannt werden an class=>method und grenzt sich vom Aufruf von Instanzenmethode wie folgt ab: obj->method
  4. Die Methode ROLL und die API Methode random_get_integer verwenden RETURNING Parameter, die lesbaren kürzeren ABAP Code ermöglichen
  5. Der CONSTRUCTOR versorgt die eigenen geschützten Attribute aus den Werten der Parameter. Der Präfix M wird für Attribute von Objektinstanzen verwendet, statische Attrubute verwenden oft den Präfix G
  6. Der CONSTRUCTOR verwendet ein Beispiel für COND # und zusammengesetzte Strings mit Parametern
  7. Die im Testtool aufgerufene Methode test_enc erzeugt die Objektinstanzen dynamisch über den Klassennamen und nicht über new <klasse>( ... ). Das ist eine Möglichkeit für dynamische objektorientierte Programmierung, wenn die Klassen beispielsweise aus Customizingtabellen kommen und die APIs über Interfaces definiert sind.