Im BSP-Praxisbuch habe ich geschrieben, dass die Feldauswahl eine
Misch-Aufgabe ist, zu der sowohl der Controller als auch die Models
etwas zu sagen haben. Daher befragt die Standard-Implementierung in
ZCL_CONTROLLER auch die involvierten Models über die Änderbarkeit des
Feldes (wofür es die Schnittstelle ZIF_MODEL_CHECK gibt).
Für Buttons empfiehlt sich in der Model-Schnittstelle die METHODE
ZIF_MODEL_CHECK~IS_EXECUTABLE, denn häufig läuft der Druck eines
Buttons auf die Ausführung einer Modelmethode hinaus. Der Controller
selbst verwaltet jedoch oft einen "Transaktionstyp", aufgrund dessen
er beispielsweise einen Beleg zum Anlegen, Ändern oder Anzeigen
anbietet. Daher hat auch er etwas zum Thema Feldauswahl zu sagen: Auch
wenn das Model nichts gegen die Änderung eines Feldes hätte, soll es
im Anzeigemodus natürlich nicht eingabebereit sein.
Wenn es gut läuft, bekommt man in der Spezifikation eine Tabelle, die
je nach Transaktionstyp angibt, welche Buttons gedrückt werden können,
welche inaktiv gezeigt werden sollen und welche überhaupt nicht zu
sehen sein sollen:
Anlegen Ändern Anzeigen
Aktualisieren aktiv aktiv inaktiv
Sichern aktiv aktiv inaktiv
Undo aktiv unsichtbar unsichtbar
Absagen unsichtbar aktiv inaktiv
Drucken unsichtbar aktiv aktiv
Wäre es nicht schön, wenn man diese Tabelle genau in dieser Form im
Coding wiederfindet?
_set_button_state_per_mode :
* FCODE \ CREATE CHANGE DISPLAY
'ACTU' active active disabled,
'SAVE' active active disabled,
'UNDO' active invisible invisible,
'CANCEL' invisible active disabled,
'PRINT' invisible active active.
Ich fand das schön und habe mich darum bemüht, den Rest so
hinzubekommen, dass ich diese Tabelle genau so im Code hinschreiben
konnte. Die vielen IF / ENDIF und CASE / ENDCASE Konstrukte in unseren
Programmiersprachen erschweren doch nur die Lesbarkeit des
Wesentlichen und sind oft so einfach gestrickt, dass man sie irgendwie
verbergen kann.
In derselben Methode, ein paar Zeilen drüber, steht das Macro, das die
obige deklarative Syntax möglich macht:
define _set_button_state_per_mode.
if lv_fcode cp &1.
case lv_mode.
when zmss_mode-create.
ev_state = zif_input_field~co_&2.
when zmss_mode-change.
ev_state = zif_input_field~co_&3.
when zmss_mode-display.
ev_state = zif_input_field~co_&4.
endcase.
endif.
end-of-definition.
Dies ist ein Grenzfall, für den ich gerade noch keine eigene Methode
spendiere. Würde das Macro ein paar Zeilen mehr enthalten, hätte ich
den Code in eine Methode ausgelagert, um z.B. das Debugging zu
ermöglichen. Das Macro selbst würde entweder ganz entfallen oder nur
noch einen passend parametrisierten Methodenaufruf enthalten, damit
nachher wie oben die bequeme Doppelpunkt/Komma-Syntax genutzt werden
kann, um den Code lesbarer zu machen. In diesem Fall fand ich es
wichtiger, den durchlaufenen Code bei Bedarf an derselben Stelle
ansehen zu können, an der auch die Deklarationen stehen.