Ich habe diesen Artikel gelesen und mich gefragt, ob wir alle switch-Anweisungen entfernen, indem wir sie durch ein Dictionary oder eine Factory ersetzen, sodass in meinen Projekten überhaupt keine switch-Anweisungen vorhanden sind.
Etwas stimmte nicht ganz.
Die Frage ist, ob switch-Anweisungen wirklich verwendet werden können, oder ob wir sie durch ein Wörterbuch oder eine Factory-Methode ersetzen (bei Verwendung einer Factory-Methode müssen natürlich mindestens switch-Anweisungen zum Erstellen der Objekte verwendet werden mit der fabrik ... aber das ist schon alles).
refactoring
switch-statement
Kanini
quelle
quelle
Antworten:
Beide
switch
Aussagen und Polymorphismen haben ihre Verwendung. Beachten Sie jedoch, dass es auch eine dritte Option gibt (in Sprachen, die Funktionszeiger / Lambda und Funktionen höherer Ordnung unterstützen): Zuordnen der fraglichen Bezeichner zu Handlerfunktionen. Dies ist z. B. in C, das keine OO-Sprache ist, und in C #, das * ist, aber (noch) nicht in Java, das auch OO * ist, verfügbar.In einigen prozeduralen Sprachen (ohne Polymorphismus oder Funktionen höherer Ordnung) waren
switch
/if-else
Anweisungen die einzige Möglichkeit, eine Klasse von Problemen zu lösen. So viele Entwickler, die sich an diese Denkweise gewöhnt hatten, verwendeten sieswitch
auch in OO-Sprachen, in denen Polymorphismus oft die bessere Lösung ist. Aus diesem Grund wird häufig empfohlen,switch
Aussagen zugunsten des Polymorphismus zu vermeiden / umzugestalten .In jedem Fall ist die beste Lösung immer fallabhängig. Die Frage ist: Mit welcher Option erhalten Sie auf lange Sicht saubereren, präziseren und wartbareren Code?
Switch-Anweisungen können oft unhandlich werden, da sie Dutzende von Fällen aufweisen und ihre Wartung schwierig machen. Da Sie sie in einer einzigen Funktion behalten müssen, kann diese Funktion sehr groß werden. In diesem Fall sollten Sie eine Umgestaltung in Richtung einer kartenbasierten und / oder polymorphen Lösung in Betracht ziehen.
Wenn dasselbe
switch
an mehreren Stellen auftaucht, ist Polymorphismus wahrscheinlich die beste Option, um all diese Fälle zu vereinheitlichen und den Code zu vereinfachen. Vor allem, wenn in Zukunft weitere Fälle erwartet werden; Je mehr Stellen Sie jedes Mal aktualisieren müssen, desto mehr Fehlermöglichkeiten gibt es. Oft sind die einzelnen Fallbearbeiter jedoch so einfach, oder es gibt so viele von ihnen, oder sie sind so miteinander verbunden, dass ihre Umgestaltung in eine vollständige polymorphe Klassenhierarchie zu viel Aufwand bedeutet oder zu viel dupliziertem Code und / oder Wirrwarr führt. schwer zu Klassenhierarchie beizubehalten. In diesem Fall ist es möglicherweise einfacher, stattdessen Funktionen / Lambdas zu verwenden (sofern Ihre Sprache dies zulässt).Wenn Sie jedoch eine
switch
an einem einzigen Ort haben und nur wenige Fälle etwas Einfaches tun, ist es möglicherweise die beste Lösung, sie so zu belassen, wie sie ist.* Ich benutze den Begriff "OO" hier locker; Ich interessiere mich nicht für konzeptuelle Debatten darüber, was "echt" oder "rein" ist.
quelle
Hier bin ich wieder ein Dinosaurier ...
Switch-Anweisungen sind an sich nicht schlecht, es geht um die Verwendung der Anweisungen.
Die offensichtlichste ist die "gleiche" switch-Anweisung, die in Ihrem Code immer wieder wiederholt wird und die fehlerhaft ist (wenn Sie dort waren und dies getan haben, würden Sie sich alle Mühe geben, es nicht noch einmal zu tun) mit der Verwendung von Polymorphismus. Normalerweise haben verschachtelte Fälle auch etwas ziemlich Schreckliches (ich hatte früher ein absolutes Monster - ich bin mir nicht ganz sicher, wie ich jetzt damit umgehe, außer "besser").
Wörterbuch als Schalter Ich finde es herausfordernder - grundsätzlich ja, wenn Ihr Schalter 100% der Fälle abdeckt, aber wenn Sie Standardfälle oder Fälle ohne Aktion haben möchten, wird es ein bisschen interessanter.
Ich denke, es geht darum, Wiederholungen zu vermeiden und sicherzustellen, dass wir unsere Objektgraphen an den richtigen Stellen zusammenstellen.
Aber es gibt auch das Argument des Verständnisses (Wartbarkeit), und dieses schneidet in beide Richtungen - sobald Sie verstehen, wie alles funktioniert (das Muster und die App, in der es implementiert ist), ist es einfach ... aber wenn Sie zu einer einzelnen Codezeile kommen, wo Sie sind Um etwas Neues hinzuzufügen, muss man dann über den ganzen Platz springen, um herauszufinden, was man hinzufügen / ändern muss.
Trotz der hohen Leistungsfähigkeit unserer Entwicklungsumgebungen halte ich es immer noch für wünschenswert, auf Papier gedruckten Code verstehen zu können - können Sie den Code mit Ihrem Finger verfolgen? Ich akzeptiere das eigentlich nicht, mit vielen guten Praktiken kann man heute nicht und das aus guten Gründen, aber das bedeutet, dass es schwieriger ist, mit Code auf den neuesten Stand zu kommen (oder vielleicht bin ich einfach nur alt ...)
quelle
Switch-Statements vs. Subtyp-Polymorphismus sind ein altes Problem und werden in der FP-Community häufig in Diskussionen zum Ausdrucksproblem angesprochen .
Grundsätzlich haben wir Typen (Klassen) und Funktionen (Methoden). Wie codieren wir Dinge, damit es einfach ist, neue Typen oder neue Methoden hinzuzufügen?
Wenn Sie im OO-Stil programmieren, ist es schwierig, eine neue Methode hinzuzufügen (da dies eine Umgestaltung aller vorhandenen Klassen bedeuten würde), aber es ist sehr einfach, neue Klassen hinzuzufügen, die dieselben Methoden wie zuvor verwenden.
Wenn Sie dagegen eine switch-Anweisung (oder deren OO-Äquivalent, das Observer-Muster) verwenden, ist das Hinzufügen neuer Funktionen sehr einfach, das Hinzufügen neuer Fälle / Klassen jedoch schwierig.
Es ist nicht einfach, eine gute Erweiterbarkeit in beide Richtungen zu haben. Wenn Sie also Ihren Code schreiben, müssen Sie entscheiden, ob Sie Polymorphismus oder switch-Anweisungen verwenden, je nachdem, in welche Richtung Sie letztere mit größerer Wahrscheinlichkeit erweitern.
quelle
Nein. Solche Absoluten sind selten eine gute Idee.
An vielen Orten bietet ein Dictionary / Lookup / Factory / Polymorphic-Versand ein besseres Design als eine switch-Anweisung, aber Sie müssen das Dictionary noch füllen. In bestimmten Fällen kann dies zu einer Verschleierung der tatsächlichen Abläufe führen und das einfache In-Line-Setzen der switch-Anweisung ist lesbarer und wartbarer.
quelle
Da dies sprachunabhängig ist, funktioniert Fall-Through-Code am besten mit
switch
Anweisungen:Entspricht
if
, mit einem sehr umständlichen Standardfall. Und denken Sie daran, dass die Bedingungsliste umso länger wird, je mehr Fehler auftreten:(Angesichts der Aussagen einiger anderer Antworten habe ich jedoch das Gefühl, den Punkt der Frage verpasst zu haben ...)
quelle
switch
als auf der gleichen Ebene wie in a betrachtengoto
. Wenn der auszuführende Algorithmus Kontrollflüsse erfordert, die zu strukturierten Programmierkonstrukten passen, sollte man solche Konstrukte verwenden, aber wenn der Algorithmus zu solchen Konstrukten nicht passt, ist die Verwendunggoto
möglicherweise besser, als zu versuchen, Flags oder andere Kontrolllogiken hinzuzufügen, um zu anderen Kontrollstrukturen zu passen .Switch-Anweisungen als Fallunterscheidung haben eine reale Verwendung. Funktionale Programmiersprachen verwenden so genannte Mustervergleiche, mit denen Sie Funktionen je nach Eingabe unterschiedlich definieren können. In objektorientierten Sprachen kann dasselbe Ziel jedoch eleganter durch Verwendung von Polymorphismus erreicht werden. Sie rufen einfach die Methode auf und abhängig vom tatsächlichen Typ des Objekts wird die entsprechende Implementierung der Methode ausgeführt. Dies ist der Grund für die Idee, dass switch-Anweisungen ein Codegeruch sind. Selbst in OO-Sprachen können Sie sie jedoch nützlich finden, um das abstrakte Factory-Muster zu implementieren.
tl; dr - sie sind nützlich, aber oft kann man es besser machen.
quelle