Tach!
Die 2. Lösung mit Event bzw. Delegate ist mir soweit klar. Die 1. Lösung noch nicht 100%ig; vor allem ist mir nicht unbedingt klar, wo der Unterschied zu Lösung 2 wäre. In meinen Augen läuft das doch wieder auf eine eventbasierte Lösung hinaus, oder?
Im Prinzip ja. Und es war nicht Debug sondern Trace. Aber Trace ist ja auch nicht zur Fortschrittsanzeige gedacht, sondern wäre dann missbräuchlich verwendet.
Das Problem hierbei ist, dass die Statusausgaben Bezug auf Zeilen nehmen, ein Kommando aber eine ganze Datei verarbeitet. Der Rückgabewert wäre dann ein möglicherweise aus sehr vielen Zeilen der Form "Zeile i konnte nicht geparst werden, weil ... Zeile i+j konnte nicht geparst werden, weil ..." bestehender String. Das erscheint mir unsauber.
Es gibt auch List<string> oder List<ParseError>.
- Problem
In den Aufrufer. Nur der weiß im konkreten Fall, was zu tun ist. Ich würde da keine höhere (Gott-)Instanz implementieren, die für sämtliche Problemfälle aller beteiligten Komponenten eine Lösung kennen soll. Gegebenenfalls muss eine Komponente die eigentliche bei ihr auftretende Exception in eine allgemeinere oder auch spezifischere (KommandoException) kapseln.
Ich bin mir nicht sicher, ob wir uns hier verstehen. Meinst du, ich soll sämtlichecatch
-Klauseln in der UI unterbringen? Das wäre natürlich insofern praktisch als ich in den Kommandos und im Transformer Exceptions einfach ignorieren kann. Aber irgendwie muss ich dann in beiden UIs jeweils zig verschiedene Exceptions abfangen.
Deswegen ja die Verallgemeinerung zu einer einzigen Exception-Klasse mit der eigentlichen im Huckepack. Allerdings nicht Exception sondern eben KommandoException o.ä.
Testbarkeit, richtig, das habe ich ganz vergessen. Man will ja auch für Kommandos, Transformer etc. Unit-Tests schreiben; das macht lose Kooplung nochmal doppelt so wichtig.
Man nennt das dann Dependency Injection. Zudem, such mal die Videos zu "google clean code talks", besonders das Don't look for Things (und die anderen auch).
dedlfix.