Das CreateOrRetrieveIfExisting Pattern

Februar 24, 2020 2 Von Andreas

Dieses Pattern ist sehr einfach und trotzdem sehr mächtig. Es hilft null pointer exceptions zu vermeiden und ermöglicht Singleton Objekte in denen Konfigurationen abgelegt werden können.

Ein Beispiel Usecase – Settings Objekte

Oftmals möchte man bestimmte Einstellungen seiner Anwendung zur Laufzeit konfigurierbar machen. Ja, man kann Konstanten dazu verwenden. Tut man dies, muss man die Anwendung aber bei Konfigurationsänderungen neu starten. Will man dies vermeiden kommt man nicht daran vorbei die Konfiguration in die Datenbank zu speichern. An ein solches Objekt hat man zwei Bedingungen:

  1. Es muss immer vorhanden sein
  2. Es darf nur ein mal vorhanden sein

Der erste Ansatz, wenn man ein Settings Objekt verwenden will ist vermutlich immer dieser:

Direkter Retrieve des Settings Objektes

Funktioniert, hat aber den entscheidenden Nachteil, dass man so nur vorgehen kann wenn man sicher ist, dass das Objekt auch existiert.

Man kann das ganze noch dahingehend erweitern:

Direkter Retrieve mit empty check

So kann man sicherstellen, dass kein Fehler geworfen wird wenn das Settings Objekt nicht existiert, allerdings tut die App mitunter immer noch nicht das, was ich von ihr erwarte.

Die Lösung:

Submicroflow Call
CreateOrRetrieveIfExisting Microflow

Wie man hier sieht wird der Retrieve des Settings Objektes in einen Submicroflow ausgelagert. Im ursprünglichen Microflow findet sich lediglich der Aufruf des Submicroflows. Dieser garantiert, dass ein Objekt zurückgegeben wird indem er das Objekt aus der Datenbank zurückgibt wenn es gefunden wurde, und wenn es nicht gefunden wurde ein neues Settings Objekt anlegt und dieses zurückgibt.

Auf einer Konfigurationsseite kann der CreateOrRetrieveIfExisting Microflow als Datasource Microflow für ein DataView verwendet werden in dem der Benutzer die Konfiguration ändern und speichern kann. So wird sichergestellt, dass das Objekt nur ein einziges mal existiert. Es empfiehlt sich die default Werte auf dem Settings Objekt sinnvoll zu setzen. Im Idealfall kann man somit sicherstellen, dass die Anwendung ohne Benutzerintervention lauffähig ist.

Man kann sich darüber streiten ob man das Settings Objekt im Create Fall auch committen sollte. Ich würde es in diesem Fall nicht tun denn es könnte bei hoher Last dazu führen, dass parallel ausgeführte CreateOrRetrieveIfExisting Microflows zu mehreren Datenbankobjekten führen. Ohne Commit, sorgt man dafür, dass das Objekt nur dann in die Datenbank gespeichert wird, wenn der konfigurierende Benutzer den Save Button drückt.