| 

.NET C# Java Javascript Exception

3
Wir benutzen in unserer 3-Schicht-Architektur zum Speichern von Objekten eine generische Methode, nämlich Object saveOrUpdate(Object object). Diese Methode steht schon auf dem Rich-Client zur Verfügung und reicht bis in eine Hibernate-Schicht. Wann ist diese generische Vorgehensweise für eine Business-Anwendung sinnvoll?
27.07.2011
oopexpert 455 1 8
Ist dies überhaupt sinnvoll?
oopexpert 27.07.2011
1 Antwort
3
Hallo oopexpert,

eine Methode [object in, object out] ist in meinen Augen prinzipiell eine gefährliche Sache. Wenn ich eine API verwenden muss (wenn ich die Wahl hätte, würde ich eine andere nehmen), die mir ein "quasi-generisches" Interface über [object in, object out] suggerieren will, ist das Erste was ich machen würde, mich davon zu befreien. Wenn ich an einer klar lokaliserbaren Stelle einen Übergang von strikter Typisierung zu einer object Schnittstelle schaffe, bewahre ich wenigstens schon mal den Rest meiner Applikation davor, sich damit auseinandersetzen zu müssen. Eine Durchgängigkeit von Hibernate bis Rich-Client würde ich akzeptieren (und auch das nur unter Schmerz), wenn auch alle 3 Schichten quasi zu einer kollabieren, also in einem Mini- oder Wegwerf-Tool/Prototyp (bei dem Wartbarkeit keine Rolle spielt).
Andernfalls müssen Persistenzbelange abgeschirmt zumindest in die Fachklasse wandern, der Client hat niemals direkten Zugriff auf Persistenzbelange, er triggert höchstens.

Vielleicht ist meine Einstellung da dem einen oder anderen zu streng, aber ich möchte es noch deutlicher machen:
Ein Konsument der oben genannten Methode wird aufgrund der Signatur der Methode zu Annahmen über gültige Parameter und Rückgabewerte gezwungen; ja nicht nur Werte, sondern auch Typen. Auch wenn es sich dokumentiertermaßen um die ich-kann-ausnahmslos-alles-speichern-oder-aktualisieren-Methode handelt, muss ich, wenn ich defensiv programmiere und robusten Code schreiben will, nach dem Aufruf der Methode im Minimalfall ein bis n Assertions platzieren, um meine Annahmen abzusichern. D.h. ich streue die Nachbedingung(en) einer Methode an alle rufenden Stellen.

Klar kann man jetzt aus der UnitTest-Ecke argumentieren, dass das über Tests alles abgesichert werden kann. Aber in meinen Augen ist es nicht Aufgabe der Tests, mangelhafte Designentscheidungen zu kompensieren. Vor allem kann ich bei einem object Parameter nur die Typen testen, die ich auch erwarte, d.h. eine notwendige (die Gutfälle) aber keinesfalls hinreichende (die Fehlerfälle) Testabdeckung erreichen.
Wenn das Kind aber schon in den Brunnen gefallen ist, würde ich mich zuerst mit Tests absichern und danach schrittweise refaktorisieren.

Fazit: Ein object-Interface ist meiner Meinung nach keine gute Sache. Wenn ich - warum auch immer - damit leben muss, biete ich allen mir nachfolgenden Schichten ein besseres Interface, dann ist zumindest Lokalität gewährleistet und der Impact von Änderungen besser abschätzbar.

Gruß
Florian
27.07.2011
ffordermaier 8,4k 3 9
Danke für Deine Einschätzung. Insbesondere die Kontextlosigkeit der saveOrUpdate-Methode macht mir zu schaffen, weil mich irgendwie das Gefühl nicht loslässt, alles testen zu müssen, weil ich nicht weiss, woher ich gekommen bin.
oopexpert 27.07.2011
Bitte, gerne. Kontextlosigkeit triffts ganz gut. Vielleicht hilfts, in kleinen Schritten in jeder Schicht eine eigenen Implementierung eines neu zu findenden Facade-Interfaces einzuziehen. Damit kannst Du zumindest schon mal Wissen über die Herkunft der Aufrufe aufbauen. Das hilft auch in den Tests. Nach und nach reduzierst Du dann die Anzahl notwendiger Facade-Implementierungen.
ffordermaier 28.07.2011
Grundsätzlich würde ich so vorgehen, wie Du es vorgeschlagen hast. Das Projekt ist vor 2 Monaten in die Implementationsphase eingetreten. Die Vorgabe ist, sich an dieses Verfahren anzupassen. Es wird fallsituativ auf Speziallfälle eingegangen. Falls die Generic hinderlich ist, wird sie an der Stelle aufgebrochen. Das geht soweit, dass man schon versucht hat, anhand der Klasse abzuleiten, welche Methode aufzurufen ist, um eine nebenläufige Aktion zu triggern.
oopexpert 28.07.2011
Ok, verstehe. Viel Erfolg bei Eurem Projekt!
ffordermaier 28.07.2011
Ich muss doch nochmal zum Besten geben, dass ich keinen Einfluss auf die Design-Entscheidung hatte. Wenn es nach unserem Architekten ginge, würde er diese generische Schnittstelle immer wieder dort einsetzen, wo er nicht absehbar endlich viele Use-Cases identifizieren muss. Ich sehe dies als einen Schlag ins Gesicht für heutige etablierte Vorgehensweisen.
oopexpert 29.07.2011
1
Da bin ich ganz Deiner Meinung. Es existieren andere Möglichkeiten, so etwas zu lösen. Zähne zusammenbeißen und durch ;-)
ffordermaier 29.07.2011

Stelle deine Java-Frage jetzt!