Dynamische Services
In den letzten Monaten habe ich mich genauer mit dynamischen Services in Form von OSGi Services auseinander gesetzt. Am Anfang war ich sehr begeistert über das einfache und erfolgsversprechende Konzept. Der Aufrufer fragt einen Dienst über einen eindeutigen Namen an und kann mit diesem anschließend arbeiten. Dabei muss ihm die konkrete Implementierung nicht bekannt sein. Er kennt den eindeutigen Namen und die Schnittstelle. Fertig.
Die Unkenntnis der Implementierung ist an dieser Stelle der große Vorteil einer Servicearchitektur. Da Komponenten somit leicht entkoppelt werden können.
Ich musste nur leider feststellen, dass das Ganze kompliziert wird wenn Services zur Laufzeit registiert und deregistriert werden können. Daraus resultieren nämlich zwei Eckpunkte, die unbedingt beachtet werden müssen:
1. Die Serviceimplementierung kann ausgetauscht werden. D.h. dass man im Notfall ein ganz anderes Serviceverhalten hat.
2. Der Service wird "auf einmal" ungültig und kann nicht mehr benutzt werden.
Beides kennt man von Internetseiten, wenn auf einmal die Seite nicht mehr erreichbar ist oder sich der Inhalt verändert hat. Gut, als Mensch ärgert man sich oder liest den neuen Inhalt durch. Aber eine Applikation kann nicht so einfach auf solche Ereignisse reagieren.
Vor allem der erste Punkte ist problematisch, da man immer Annahmen über den Service macht, auch wenn sie sich nicht in der Schnittstelle äußern. Natürlich sind zustandslose Services unproblematischer, aber auch dort kann es Probleme geben. Man stelle sich einen Verschlüsselungsservice vor, der auf einmal nicht mehr mit MD5 sondern SHA-1 Hashwerte erzeugt.
Der zweite Punkt ist wichtig für Geschäftsanwendungen, in denen die Geschäftslogik meistens auf einem Server sitzt und die Benutzer nur mit einem Client ohne Geschäftslogik arbeiten. Wird der Zugang zur Logik mit Hilfe von dynamischen Services geregelt, so muss der Client eigentlich von Grund auf so aufgebaut sein, dass diese Services zur Laufzeit wegfallen bzw. ihr Verhalten ändern können. Der Benutzer muss in solchen Fällen mit einer entsprechenden Fehlermeldung benachrichtigt werden, ohne das der Client abstürzt oder sich unkontrolliert verhält. Desweiteren muss die Clientrepräsentation der Daten bei einem Servicewechsel konsistent gewechselt werden. Dabei stellen sich unterschiedliche, prinzipielle Fragen. Was passiert wenn der Benutzer gerade bei einem Vorgang ist? z.B. der Abarbeitung einer Rechnung? Wie verärgert man den Benutzer an dieser Stelle am wenigsten?
Ich denke, dass genau das der größte Nachteil von dynamischen Services ist. Vorhandene Clients können nur mit viel Aufwand auf solche Services umgestellt werden und sind insgesamt komplizierter zu programmieren, da man sich auf das Vorhandensein einer Geschäftslogik nicht verlassen kann. D.h. zum Einen muss man abstrakter Programmieren und viele Ausnahmenregelungen bedenken und zum Anderen muss die Benutzerführung geschickter, vielleicht auch transparente bzgl. der genutzen Services, angelegt werden. Welche Erfahrungen habt ihr mit solchen Architekturen gemacht?
So nebenbei stellt sich mir die Frage, ob Services nicht per Definition dynamisch sind und dynamsiche Services somit doppelt gemoppelt sind?
Labels: Softwareentwicklung