Jo. Gerade heute wieder einen Kommentar auf eine Antwort gelesen:(haha, vergifteter gehts nicht mehr)
Mhm, hatte erst gerade kürzlich die Pattern in einer Vorlesung. Da wurde z.B. ernsthaft gesagt, man solle das Factory-Pattern benutzen, um einfacheres Refactoring zu erlauben. Nur in einem einzigen Fall finde ich das zu bevorzugen: Wenn idiomatisch ein ::create() benutzt werden kann, das einige immergleiche Parameter des Basisklassenkonstruktors bindet.Krampfhafte Patternisierung ist böse
(Manche Pattern, wie das Visitor-Pattern bei ASTs, sind für einige wenige Anwendungsbereiche extrem gut geeignet).
Aber selbst Wikipedia schreibt korrekt:
Nur kommt das in den Vorlesungen nicht so rüber. Es heisst schlicht, Patterns seien das einzig Wahre, dann bekommt man in einer Prüfung irgendeinen 100-Zeilen-Code vorgesetzt und muss dann sagen, dass es schlecht ist, new String statt StringBuilderFactory().build().make() zu benutzen, weil letzeres ja so viel erweiterbarer sein soll.Der erfolgreiche Einsatz von Entwurfsmustern in der Vergangenheit kann dazu verleiten, die Entwurfsmuster als Wunderwaffe und Garant für gutes Design anzusehen. Unerfahrene Entwickler können geneigt sein, möglichst viele bekannte Muster zu verwenden, und dabei übersehen, dass in ihrem Fall vielleicht eine elegantere Lösung ohne den Einsatz von Mustern möglich wäre. Entwurfsmuster garantieren nicht, dass der Entwurf gut ist. Insofern ist die Anwendung zu vieler oder ungeeigneter Entwurfsmuster ein Antimuster.
Das sind die Professoren, die ihre Semantischen Analyzer auch ohne Overflow arbeiten lassen, weil es ja so viel Sinn macht, einen möglichen Resultatbereich eines Integers von [0, \inf[ zu haben
Hui, wird da Pi in die tausendste Stelle berechnet oder 1GB Daten durchsucht?Ein RestAPI-Ding, bei dem der einfachste Request 20sec braucht.
Das ist zwar fast wieder eine andere Diskussion, aber wieso wären hier Returnvalues nicht zu bevorzugen (die meisten Funktionen von CryptoPP geben ohnehin void zurück)? Das Problem mit Exceptions ist ja gerade, dass sie irgendwann mal mitten in einem Code, der Libraryfunktionen benutzt, auftreten können. Catchen muss man die Exceptions ohnehin möglichst nahe am throw, sonst bekommt man sehr schnell einen Inconsistent State. Und ähnlich wie mit new, dessen throw ich wirklich fürchte, welcher eigentlich nicht nötig ist, da man auch auf nullptr prüfen kann, sehe ich keinen Grund für Exceptions, da man ja einfach einen bool/bitset/errnum zurückgeben könnte, der dann halt zu prüfen ist.(Die Exception für falsche Keys hört sich für mich gar nicht so schlimm an...)
Ich weiss schon, dass u.a. bei Java die Exceptions meistens recoverable sind, und ich sehe auch das Argument, dass es eher unerwartet ist, dass Fehler geschehen (eine sehr optimistische Einstellung). Aber warum wird dann eine Exception so lange automatisch rethrowt, bis es jemand handelt, und zerschiesst dabei alle Stacks davor? Warum wird nicht erzwungen, dass Exceptions nur eine Stufe durchdringen können, um es überschaubar zu halten? Bei einem Retry würde dann ja immer alles komplett neu aufgebaut, was auch wieder kostet. Und wenn etwas wirklich kaputtgehen kann, dann müsste das ja schon im Vorherein klar sein, und man könnte ein Callback setzen.
Wobei das meines Wissens im Styleguide für Kernelcode ist. Wie sehr das durchgesetzt wird, weiss ich aber auch nicht, und i.d.R. sind auf den tieferen Stufen auch weniger Unterscheidungen nötig.dass man mehr als drei verschachtelte Level von Schleifen/if/... in der Realität nie sehen wird lol
20 SetterAuf die Frage, was man bei Funktionen mit 20 Parametern (bei der man die Parameterliste nicht ädnern kann!) und gleich am Anfang 200 Zeilen Validierung der Parameter, bevor es zum eigentlichen Sinn der Funktion kommt, tun soll, konnte mir bisher niemand von solchen Leuten eine überzeugende Antwort geben.
Immer beliebt ist der Spruch: "Wer 11 Parameter hat, hat vermutlich einen vergessen." Ja ne is klar. Das sind dann aber auch die Vögel, die 300 Werte in ein JSON-Objekt schreiben und dann 2 davon benutzen. Sind ja keine Parameter oder so. Oder sie machen es viel klüger und erstellen einzig für die Verwaltung der Parameter ein Objekt, selbstverständlich auf dem Heap, damit der ach so lahme Stack nicht benutzt werden muss. Beim ersten WinAPI-Code würden die Leute ja einen Schreikrampf kriegen...
Ich meine, keiner mag viele Parameter, aber manchmal müssen sie hin und dann sieht es halt nicht sehr gut aus, aber meine Güte, diese Funktionen werden i.d.R. nicht als Interface gegeben, sondern intern benutzt.
Doch, so oder so ähnlich machen das recht viele Leute.Wohl kaum.
Ah ja, Wiederverwendbarkeit. Eigentlich nichts schlechtes, aber die Leute rollen immer erst die Strukturen aus und machen dann den eigentlichen Arbeitscode, sodass immer etwa 3 Wrapperklassen sinnlos vor sich hindümpeln. Sieht halt schon viel besser aus, wenn man keinen Code sieht Ich halte es grundsätzlich eher konservativ: Solange es lesbar ist, ist alles ok. Wird es zu komplex, wird ausgelagert....Erinnert mich an einen Kollegen, der tatsächlich jedes if-foo-then-error-4 in zwei Klassen ausgelagert hat (eine für das if, eine mit den Fehlerdaten). Könnte ja wiederverwendbar sein. War es teilweise auch, aber natürlich keine Nettoersparnis an Zeilen und Arbeitszeit. Inzwischen hat sogar er eingesehen, dass es Unsinn ist.
"Wenn eine Funktion so viele Zeilen hat, macht sie zu viel gleichzeitig" (auch auf Klassen anwendbar, halt mit Member etc.).Hast du auch mal einen Grund bekommen? Also einen außer "ich mag es nicht" und/oder "RandomPersonImInternet mag es nicht"?
Und es ist wohl wahr, ich lagere nur dann aus, wenn es wirklich der Lesbarkeit hilft und Performance nicht allzu wichtig ist oder wenn ich dieselbe Funktionalität mehrmals brauche. Aber bei langen if-elses mit klarer Sortierung; warum sollte ich da gross auslagern? Dass langer Code per se schlecht sein soll, ist auch eine Folge von missverstandenem OOP (wie so vieles), aber leider hält sich das ja hartnäckig.
Das ist, denke ich, eines der Probleme: Man schreibt immer nur Samplecode an den Bildungseinrichtungen, nie richtigen Code. Will man irgendwas komplexes machen, nimmt man dann die einfachste Bibliothek und fertig; man muss wenig Code schreiben. Entsprechend wird auch eher die Form statt die Funktion bewertet, und das zieht sich halt so durch.Erinner sie doch bitte mal, dass wir nicht Modedesigner sind, sondern was praxistaugliches machen wollen.
Letztens über Swift gelesen: Hat ja so geile Features wie return type overloads. Ja, man kann es sich denken:
Code:
let a: Double = -(1 + 2) + -(3 + 4) + -(5)
In Kurzform: Durch die overloaded return types gibt es exponentielle Type-Inference-Komplexität. Aber hey: Immerhin zahlt man nur mit 20s compiletime bei solch einfachen Expressions für dieses tolle Feature, das keiner je vermisste. Und: Es sieht halt besser aus, da spielt Performance keine Rolle.
Aber ich bin ja auch der Meinung, man dürfe
Code:
//Für kurze statements (~< 10 LOC)
if () {
stmt();
}
//Für "normale" statements
if()
{
stmt();
}
//Für 1 LOC statements
if()
stmt();
Das war sicherlich eine Übertreibung, aber diese Meinung ist sicher in der Minderheit (oder die anderen sind einfach lauter, kann ja auch sein).du bist nicht allein
Eieiei, was für ein Rant. Aber muss ja auch ab und zu sein.
Gruss
cwriter