lilith2k3 Geschrieben 9. Februar 2013 Teilen Geschrieben 9. Februar 2013 Hallo, zunächst eine Entschuldigung an den Mod, der evtl. das Thema verschieben darf, weil hier nicht der geeignete Ort ist. Es hat nichts mit Algorithmik per se zu tun. Aber mir ist echt auch nach 5 Minuten kein Subforum eingefallen, wo ich das Thema hätte anlegen können. Soetwas wie "Softwarearchitektur" oder so gibt es ja leider nicht. Zumindest hab ich sowas nicht gefunden Meine Frage ist im Grunde eine philosophische und es gibt natürlich kein Patentrezept - das ist mir klar. Aber ich möchte mir zumindest Meinungen und Rat einholen. Es geht darum, dass viele Softwareprojekte eben sogenannte "n-tier" oder "Multilayer" Anwendungen sind. Zur Diskussion vielleicht folgendes Beispiel aus meiner Praxis: Ich habe eine Webanwendung, die per REST Daten an's Backend liefert. Das ganze wird mittels MVC-Framework realisiert (welches, ist in dem Falle ja mal egal). Das heißt, nach dem Dispatching schlagen die Daten im Controller auf. Der Controller reicht die Sachen an den Service-Layer weiter. Der Servicelayer seinerseits kümmert sich um die Validierung der Daten. Anschließend werden die Daten im DAL (Data-Access-Layer) zum Persistieren aufbereitet. Die Frage, die sich nun stellt: Wo schmeiße ich welche Exceptions und wo fange ich die wieder auf? Bisher werfe ich Validierungsexceptions im Service-Layer und fange sie im darüberliegenden Layer (also dem aufrufenden Controller), wo die Sachen darüber hinaus auch weggelogged werden. Aber was mache ich beispielsweise mit Exceptions aus dem DAL? Fange ich die im Service-Layer ab und werfe von da ausgehend eine für den Layer eigene Exception? Also quasi: ich fange eine SQL-Exception im Data-Layer und packe eine "Data-Layer-Exception" drumrum. Anschließend fange ich die Exception im Service-layer und packe eine "Service-Layer-Exception" drumrum und schmeiße die wieder weiter nach oben .Oder lasse ich alle Exceptions einfach "hochbubblen" und fange die im obersten Layer ab? Fachlich richtiger wäre es wahrscheinlich die Exceptions im entsprechenden Layer aufzufangen, aber andererseits hat man dann einen Rattenschwanz an Exceptions. Das kann ja schnell Inflationär werden. Bin gespannt auf die Diskussion. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Pixie Geschrieben 9. Februar 2013 Teilen Geschrieben 9. Februar 2013 Ich habe jetzt wenig bis keine Ahnung von Architekturen... aber aus einem rein pragmatischen Ansatz heraus würde ich sagen: Dort, wo sie relevant sind. Wie im richtigen Leben. Wenn eine Exception durch eine Anwenderaktion ausgelöst wurde, sollte der Anwender davon in geeignetem Umfang Kenntnis bekommen, damit er z.B. nicht fälschlich davon ausgeht, dass seine Datenänderungen geschrieben wurden. Er sollte auch wissen, was er tun kann/sollte. Sollte er jemanden informieren? Wenn ja, welche Informationen sollte er weitergeben? Findet die Informierung bereits an anderer Stelle statt? SQL-Exception wegen nicht maximal wachsender und jetzt voller Protokolldatei... da kann dann auch gleich die nächsthöhere Schicht per EMail den Admin informieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
uenetz Geschrieben 10. Februar 2013 Teilen Geschrieben 10. Februar 2013 Interessanter Beitrag! ... :uli Grundsätzlich würde ich mal sagen, dass Exceptions dann geworfen werden sollen, wenn es angebracht ist (Bsp.: Fehlbedienung, fehlende Connection, etc.). Wenn es sich bei dem Produkt um eine Client-/Serveranwendung handelt, ist es natürlich eine Überlegung wert, wem was und wie gemeldet wird, oder wie und was abgefangen wird. Daher würde ich die Überlegung anstellen, was man sofort meldet, oder was man z.B. in einer Datenbank loggen kann, damit die Administration ggf. darauf reagieren kann/muss. Bei Critical Error denn auch noch eine Information an die Administration (per Mail, SMS, etc.). Ich denke wie groß man den Aufwand betreibt, hängt 1. vom Produkt, 2. von den Vorgaben, 3. von der Quallitätssicherung, etc. ab. Das war es mal grob/adhoc, was mir zu diesem Thema eingefallen ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
pintman Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Ich würde Pixie zustimmen und noch ergänzen: Exceptions sollten da gefangen werden, wo sie auch tatsächlich behandelt werden können. Natürlich hängt es auch immer von der Sprache und dem Szenario ab: wenn ich selbst der einzige Anwender bin und jederzeit in kritische Aktionen eingreifen möchte, würde ich gar nicht werfen, sondern direkt einen Debugger öffnen, um das Problem zu lösen - besonders bei Smalltalk und Lisp-Systemen geht das ganz gut. Java und C# sind mit Quelltextersetzungen zur Laufzeit nicht so gut aufgestellt, so dass man dort häufiger neu deployen muss, wenn Fehler auftreten. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lilith2k3 Geschrieben 11. Februar 2013 Autor Teilen Geschrieben 11. Februar 2013 Ich würde Pixie zustimmen und noch ergänzen: Exceptions sollten da gefangen werden, wo sie auch tatsächlich behandelt werden können. Ich nehme dieses Zitat mal als Ansatzpunkt, meine Problemstellung weiter zu beleuchten: Behandeln (im Sinne von "abfangen, Fehler loggen und ggf. Fehlermeldung generieren") kann ich die Exception in jedem Layer. Es ist die Frage, ob ich für jeden Layer eigene Exceptions generieren und werfen soll, oder ob ich alle aufkommenden Exceptions -egal von wo- im Controller fange und letztlich nur noch eine Fehlermeldung an den Benutzer mache. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Interessanter Beitrag! ... :uli Daher würde ich die Überlegung anstellen, was man sofort meldet, oder was man z.B. in einer Datenbank loggen kann, damit die Administration ggf. darauf reagieren kann/muss. Bei Critical Error denn auch noch eine Information an die Administration (per Mail, SMS, etc.). Ich denke wie groß man den Aufwand betreibt, hängt 1. vom Produkt, 2. von den Vorgaben, 3. von der Quallitätssicherung, etc. ab. Das war es mal grob/adhoc, was mir zu diesem Thema eingefallen ist. Logging niemals in Datenbanken ... ;-) Anwendungen sollten außerdem Administratoren nicht informieren. Kritische Fehler sollten im Eventlog landen und vom Monitoring System weitergemeldet werden. SRP / SoC und so Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
pr0gg3r Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Exceptions fängt man dort ab, wo sie auftreten. Hallo, Fachlich richtiger wäre es wahrscheinlich die Exceptions im entsprechenden Layer aufzufangen, aber andererseits hat man dann einen Rattenschwanz an Exceptions. Das kann ja schnell Inflationär werden. Ich weiß jetzt nicht was du meinst. Meinst du, dass du jede Menge exceptions hintereinander reinprogrammieren musst, oder, dass eine Exception nach der anderen geworfen wird, sobald eine auftritt? Bei ersterem: Ein Gruß an diese Stelle an alle Java-Programmierer, die schmeißen ja mit unendlich Exceptions um sich Bei letzterem: Normal führt man das Programm ja nicht weiter aus, darum wird nur die unterste Exception geworfen und fertig. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
a3quit4s Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Ich weiß jetzt nicht was du meinst. Meinst du, dass du jede Menge exceptions hintereinander reinprogrammieren musst, oder, dass eine Exception nach der anderen geworfen wird, sobald eine auftritt? Event Bubbling, kennst du es? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
pintman Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Ich würde logging nicht als Behandlung einer Exception interpretieren. So etwas kann man auch als Aspekt in den Code einweben. Wenn eine Exception bei der Eingabe von Daten durch einen Nutzer auftritt, kann der Nutzer durch eine Korrektur der Eingabe, den Fehler beheben. Wenn in einem Cluster ein Node ausfällt, kann durch einen anderen Node ein Engpass vermieden werden. In den meisten Fällen kann ich jedoch nichts machen, außer die Exception zu loggen. Das ist interessant für den Programmierer, weil es meist auf einen Bug hindeutet. So etwas würde ich auf der obersten Ebene loggen - oder noch besser: als Apsket einweben -, um der Businesslogik nicht vorzugaukeln, dass tatsächlich etwas behandelt würde. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
pr0gg3r Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Event Bubbling, kennst du es? Ja, aber ich weiß nicht was du mir damit sagen möchtes bzw. den Zusammenhang mit Exceptions. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lilith2k3 Geschrieben 11. Februar 2013 Autor Teilen Geschrieben 11. Februar 2013 Ein Gruß an diese Stelle an alle Java-Programmierer, die schmeißen ja mit unendlich Exceptions um sich Ja. Ich liebe diese Stacktraces:rolleyes: Aber genau um sowas geht es mir. Bei letzterem: Normal führt man das Programm ja nicht weiter aus, darum wird nur die unterste Exception geworfen und fertig. Warum führt man das Programm nicht weiter aus? Beispiel: Exceptions zur Validierung... Illegale Objektzustände können so vermieden werden. Es kommt zu einer Validierungsexception und nach einer Benutzerinfo geht's wieder weiter im Programm. Oder Mehrstufiges Beispiel: SQL-Exception wird im DAL gefangen und in einer "DatabaseException" gekapselt und weitergereicht. Auffangen könnte man die an der "Oberfläche" und den Benutzer informieren, dass die Datenbank schrott ist, oder man fängt sie im Service-Layer auf und packt nochmal eine Service-Exception drum, die dann letzten Endes auch wieder an der Oberfläche ankäme, wo sie ähnlich behandelt würde. Allerdings hätte man das Designprinzip für Layer insoweit verletzt, als dass ein Layer nur einen Anknüpfungspunkt zum nächsten darunterliegenden haben sollte. Ich würde logging nicht als Behandlung einer Exception interpretieren. Fachlich gesehen gebe ich Dir recht; umgangssprachlich ist logging auch eine Art der Behandlung Es ging darum, den Fehlerfall zu dokumentieren. Und nicht in jedem Fall ist ein Programmabbruch bei einer Exception nötig, vorallem, wenn es sich um Custom-Exceptions handelt. Das ist interessant für den Programmierer, weil es meist auf einen Bug hindeutet. So etwas würde ich auf der obersten Ebene loggen - oder noch besser: als Apsket einweben -, um der Businesslogik nicht vorzugaukeln, dass tatsächlich etwas behandelt würde. Aber es könnte dennoch wert sein, den Benutzer darüber zu informieren, oder? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 11. Februar 2013 Teilen Geschrieben 11. Februar 2013 Anderer Ansatz ist auch, muss für jeden Fehler wirklich auch eine exception geworfen werden. Exceptions sind teuer. Es haben auch leute schon nullreference exceptions zur Validierung verwendet. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lilith2k3 Geschrieben 11. Februar 2013 Autor Teilen Geschrieben 11. Februar 2013 (bearbeitet) Anderer Ansatz ist auch, muss für jeden Fehler wirklich auch eine exception geworfen werden. Exceptions sind teuer. Wie sähe denn der "andere Ansatz" konkret aus? Wir können ja mal ein konkretes Beispiel durchspielen. Ich fang mal an und Du kannst mir ja Verbesserungsvorschläge geben: Konkretes Szenario: Lagerverwaltung (nicht, dass ich derzeit eine entwickeln muss *g*). Es gibt Lagerhallen (L1,L2,L3,L4 etc.), Gänge (01,02,03,04 etc.), Regale (01,02,03,04 etc.), Regalreihen (01,02,03,04 etc.) Fachnummern (01,02,03,04 etc.). Für einen Lagerort bedeutet das, das er eindeutig durch einen 5-Tupel aus den Mengen gekennzeichnet ist: L101010101 wäre quasi der erste Lagerort im Lager 01. Folgendes Anwendungsszenario: Der Benutzer möchte das Lager initialisieren. Er möchte gern in einer Bulk-Operation das Lager von L101010101 bis L110101010 vorbereiten. Das kann alles im Frontend geklärt werden. Die Operation wird mittels POST an einen REST-Endpunkt übermittelt. Dort ist auch mein konkreter Ausgangspunkt oder das, was ich als "Oberfläche" bezeichne. Dort findet ein Aufruf statt, der sich in etwa so liest: LagerverwaltungsService.erzeuge(Lagerorte); Fertig. Im Lagerverwaltungsservice befindet sich folgendes Transaktionsskript: MassenJobValidator.validiere(Anforderung) ... [/php] Dort kommt es schon zu einer Reihe von ungewünschten Zuständen: 1) Die Range ist komplett verkehrt herum - also alle Angaben auf "von" sind größer als alle Angaben von "bis" 2) Es gibt diverse Maxima, die nicht überschritten werden dürfen. 3) Lagerorte sind unbekannt (e.g. "Ö1" gibts nicht, das wäre ein Tippfehler) Dafür habe ich jeweils eigene Exceptions. Entweder liefert der Validatorservice ein "True" oder es fliegt eine entsprechende Exception. Und "Nein!", ich finde [i]return[/i]-Values unzweckmäßig. Returns können ignoriert werden, Exceptions nicht. Des weiteren im Skript: [php] ... Lagerort ort=generiereLagerOrt(); ... Lagerort generiereLagerOrt(){ Lagerhalle halle=LagerHallenService.holeHalleMitId(hallenId); if(Lagerhalle==null) throw new AmArschKeineLagerhalleDaException(); return Lagerhalle } Und dergleichen mehr. Also quasi gibt es hier einen Haufen Exceptions, die ich zur "intelligenten" Fehlerbehandlung eingebaut habe. Wie sähe denn ein gegenentwurf aus? Bearbeitet 11. Februar 2013 von lilith2k3 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Gast runtimeterror Geschrieben 12. Februar 2013 Teilen Geschrieben 12. Februar 2013 Ich bin ganz klar dafür, Exceptions in jeder Ebene zu wrappen. D.h. Exception fangen, ggf. Loggen und (falls für die darüberliegende Ebene relevant) erneut zu werfen (mit der verursachenden Exception als Cause). Das Argument mit der Performance halte ich für irrelevant. Mit der Entscheidung für MVC stellt man bereits eine saubere Architektur über die Performance. Warum sollte ich in den oberen Ebenen IOExceptions behandeln, wenn die Implementierung in den Ebenen darunter austauschbar ist? Meinen Chef interessiert nur, dass ich zu spät zur Arbeit erscheine; Cause: Verkehrsstau, Cause: Unfall, Cause: Schlechte Sicht, Cause: Nebel, Cause: Wetteranomalie, Cause: Klimaerwärmung, Cause: CO2-Emissionen, Cause: Verbrennungsmotoren, ... Wenn ich meinem Chef jetzt mit "Klimaerwärmung" als Grund für meine Verspätung komme wird der mich zurecht für bekloppt halten. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SilentDemise Geschrieben 12. Februar 2013 Teilen Geschrieben 12. Februar 2013 was hat denn MVC mit performance zu tun? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
pintman Geschrieben 12. Februar 2013 Teilen Geschrieben 12. Februar 2013 Meinen Chef interessiert nur, dass ich zu spät zur Arbeit erscheine; Cause: Verkehrsstau, Cause: Unfall, Cause: Schlechte Sicht, Cause: Nebel, Cause: Wetteranomalie, Cause: Klimaerwärmung, Cause: CO2-Emissionen, Cause: Verbrennungsmotoren, ... Wenn ich meinem Chef jetzt mit "Klimaerwärmung" als Grund für meine Verspätung komme wird der mich zurecht für bekloppt halten. Danke für das schöne Beispiel. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Gast runtimeterror Geschrieben 12. Februar 2013 Teilen Geschrieben 12. Februar 2013 MVC erhöht die Übersichtlichkeit und Wiederverwendbarkeit durch die Einführung einer Abstraktionsebene. Diese bringt naturgemäß Schnittstellen mit, welche ohne die Abstraktion nicht erforderlich wären. Schnittstellen erhöhen die Tiefe eines Stacktraces und damit den Overhead beim Aufruf von Methoden der unteren Ebenen, was Performance-Einbußen mit sich bringt. Spaghetticode und flach strukturierter Code sind in der Regel schneller als die Implementierung generischer Ansätze - mit ihren eigenen Vor- und Nachteilen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 12. Februar 2013 Teilen Geschrieben 12. Februar 2013 Ich hab den Thread jetzt nur mal überflogen. Es ist die Frage, ob ich für jeden Layer eigene Exceptions generieren und werfen soll, oder ob ich alle aufkommenden Exceptions -egal von wo- im Controller fange und letztlich nur noch eine Fehlermeldung an den Benutzer mache. Das mag einem im ersten Moment vielleicht sauber vorkommen, aber im Endeffekt erzeugst du damit einen sehr großen Overhead an Code der dir keinen praktischen Nutzen bringt. Von daher ist die Aussage das man Exceptions nur da fangen sollte wo man sie auch behandelt schon richtig. Das heißt je nach Framework/Technologie auch das du sie evtl. nur auf dem Client abfängst um dort eine Meldung für den Benutzer auszugeben da das durchreichen bis dorthin automatisch geschieht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.