Lade...
 

Extern (2.Beispiel)

Kundenableitungen definieren

Gegeben sei folgende imaginäre Projektstruktur, bei der das Programm mit folgenden Parametern gestartet wird:

cx_osuo.exe project.cxp --extern_file project.ext

 

project.ext
Msg(PROCESS_DATA) Extern(basicFunctions, File(basicFunctions.mod)) Extern(advancedFunctions, File(advancedFunctions.mod)) : basicFunctions Extern(businessLogic, File(businessLogic.mod), triggeredBy(PROCESS_DATA)) : advancedFunctions

 

project.cxp
Module(project) [ INITIALIZE: // ... data SendMsg(PROCESS_DATA) // ... ]

 

Nun soll das Verhalten des Moduls businessLogic für einen Kunden (Bsp: "ACME") angepasst, also eine kundenspezifische Ableitung geschrieben, werden. Da nur ein kleiner Teil der Funktionalität angepasst werden soll, macht es wenig Sinn, das gesamte Modul neu zu schreiben, sondern stattdessen den Großteil der bestehenden Logik von dem Modul businessLogic durch Vererbung zu übernehmen und nur einen spezifischen Teil anzupassen. Das Modul gänzlich neu zu schreiben hätte auch den Nachteil, dass Anpassungen am businessLogic-Modul im Hauptprojekt keine Auswirkungen auf das Kundenprojekt hätten.

Die Anpassung lässt sich ganz einfach definieren, ohne dafür den Code des Hauptprojekts anzupassen. Hierzu muss lediglich eine .ext-Datei für den Kunden mit folgendem Inhalt angelegt werden:

acme.ext
#include "CX_SYSTEM\\project.ext" Extern(businessLogic_acme, File(businessLogic_acme.mod), triggeredBy(PROCESS_DATA), overwrites(businessLogic)) : businessLogic

Und hier eine skizzierte Modulimplementierung für das Kundenmodul. Die Angabe des Basismoduls nach Module(...) ist nicht notwendig, da es eine Extern()-Angabe zu dem Modul gibt und das Basismodul dort definiert ist.

businessLogic_acme.mod
Module(businessLogic_acme) [ Define(CoreLogic) // Some modified logic ; ]

 

Mit dieser Anpassung muss dass Projekt jetzt auch mit der neuen .ext-Datei wie folgt gestartet werden:

cx_osuo.exe project.cxp --extern_file acme.ext

Das Projekt wird jetzt an allen Stellen die angepasste Kundenlogik verwenden, da das original-Modul durch overwrites(businessLogic) deaktiviert wurde. Mittels overwrites(...) lässt sich eine Standardlösung an Kundenwünsche beliebig anpassen, ohne diese Anpassungen in den Standard direkt einbauen zu müssen. 

 

Was heißt deaktiviert?

Das Modul ist nicht wirklich deaktiviert. overwrites(...) bewirkt lediglich, dass das Modul beim Senden der früher angemeldeten triggeredBy(...)-Nachrichten nicht mehr geladen wird. Auch wird der Provider abgemeldet, falls es sich per provides(...) als solches registriert hat. Da es nicht mehr auf Messages reagiert, wirkt es "deaktiviert". Ein anderes Modul kann aber trotzdem von einem "deaktiviertem" Modul ableiten und so dessen Funktionalität verwenden.

Das Modul ist also in der Hinsicht deaktiviert, dass es nicht mehr selbst aktiv wird, sobald eine früher angemeldete Trigger-Message gesendet wird, es kann aber in Ableitungen weiterhin unverändert verwendet werden.

 

Was würde ohne overwrites passieren?

Da overwrites(...) die Trigger-Messages des ursprünglichen Moduls deaktiviert, würde es ohne Überschreibung zwei Module geben, die auf die gleichen Messages reagieren und in SendMsg(PROCESS_DATA) würde das System versuchen, zwei Module zu laden, wobei das eine von dem anderen Abgeleitet ist, was verboten ist, denn ein Modul kann nicht instanziiert werden, wenn es gleichzeitig ein davon abgeleitetes Modul gibt. Das System würde in dem Fall nur das abgeleitete Modul laden und würde sich somit in diesem Fall genauso verhalten, wie mit der Angabe von overwrites(...).

Achtung: Auf dieses Verhalten sollte man sich nicht verlassen, da so eine Konstellation trotzdem einen Fehler darstellt und in zukünftigen ClassiX-Versionen beim Start als Fehler gemeldet werden könnte.

Würde in dem abgleiteten Kunden-Modul jedoch auch das triggeredBy(...) fehlen, dann würde das System einen Fehler liefern, weil die Message nur das Basismodul instanziieren würde, was nicht erlaubt ist.