Technische Anforderungsanalyse:
- Transparenz ist oberstes Gebot. Ein Aufrufer darf es nicht gewahr werden, daß der unmittelbar Gerufene (also der "Dispatcher") nur ein Mittelsmann ist, der den Aufruf je nach anwendbaren Bedingungen und Regeln an einen jeweiligen mittelbar Ausführenden gibt.
-
glue code innerhalb der "Fach-Anwendung" oder sonstige hacks im Anwendungscode, die darauf eingehen, dass überhaupt ein Dispatch oder eine Delegation stattfindet sind verboten.
- Der Dispatch bzw. die Delegation soll bzw. muß anhand von vorab festgelegten Regeln aber abhängig vom Laufzeit-Kontext erfolgen. Dabei sollen alle am Dispatch beteiligten Elemente zustandlos (stateless) sein.
- Der Regelsatz des Dispatcher soll möglich einfach zu konfigurieren sein.
- Ein Dispatcher muß eine beliebige Anzahl von Regeln verarbeiten können und anhand dieser Regeln jeweils auf eine beliebige Anzahl von Delegates verweisen können.
Ausarbeitung der Lösung:
Für konkrete Umsetzung der Lösung erschien es am sinnvollsten einen aspektorientierten Ansatz zu wählen. Als lösungsrelevante AOP-Methoden kristallisierten sich der
around advice (bzw.
method interception) und
introduction (auch als
mixin bekannt) heraus.
Für die technische Umsetzung der Lösung wurde das
Spring-Framework als Basis verwendet. Spring bietet ein leichtgewichtiges, gut konfigurables und außerdem sinnvoll vorausgebautes und dokumentiertes Aspekt-Framework, das für den angestrebten Zweck sehr geeignet erschien.
Für die Umsetzung der Lösung in Code und Spring-Beans-Xml konnten die innerhalb des Spring-Frameworks sehr klar verständlich und einfach benutzbar angelegten Framework-Fähigkeiten erweitert und kombiniert werden. Wesentliche benötigte Funktion durch eine Erweiterung des
DelegatingIntroductionInterceptor
und Implementierungen des Interfaces
IntroductionInfo
bereitgestellt werden. Für die konfigurable Handhabung der Dispatch-Bedingungen und deren bedingsabhängiger Verknüpfung zu den jeweiligen Arbeitsobjekten wurden zur Verdeutlichung des angestrebten Kontrakts eine Anzahl von Interfaces entworfen und dokumentiert.
Diese Interfaces stellen eine Art minimalistische Erweiterung zum Spring-Framework dar, die aber soweit man sie benutzen will, aufgrund dessen, dass sie sich an der Benutzungssemantik des Spring Frameworks orientieren, leicht verständlich sein sollten.
Durch die Adaption und Verwendung des von Spring angebotenen
introduction-Proxy besteht die Möglichkeit ein als Bean in einem Spring-Kontext befindliches Target-Objekt als Implementor einer beliebigen Anzahl von Interfaces erscheinen zu lassen, also ein sogenanntes
mixin bzw. eine "scheinbare Mehrfachvererbung" zu erzielen. Alle auf diese Art "introduzierten" Methoden bilden automatisch
Join Points für
Around Advices. Mit anderen Worten heißt das, alle Aufrufe die auf die "introduzierten" Methoden abgesetzt werden, werden zuerst einmal abgefangen (
method interception) und können 1.) hinsichtlich ihrer Parameter, 2.) hinsichtlich des tatsächlichen Ausführungszieles und 3.) hinsichtlich der Rückgabewerte innerhalb des Aspekts beliebig modifiziert werden.
Der auf diese Art arbeitende Dispatcher tritt gegenüber einen Aufrufer (
caller) immer als der scheinbar direkt Aufgerufenen (
callee) auf, ist aber stets nur
man in the middle der den Aufruf an einen zur Laufzeit anhand der konfigurierten Regeln und hinterlegten Zielobjekte bestimmten mittelbar Aufgerufenen weitergibt.