Verfolgt man die Geschichte der Programmierung, lässt sich feststellen, dass if-Konstrukte den Zeiten der funktionalen Programmierung entstammen, aber den Sprung in die meisten objektorientierten Programmiersprachen (OOP) geschafft haben.
In der Schifffahrt sagt man, ein guter Kapitän nutzt im Seenotfall alle ihm zur Verfügung stehenden Mittel. Meist geht es in unseren Programmieraufgaben aber nicht ums Überleben, sondern um zukunftssicheren, verständlichen und vor allem erweiterbaren Code.
Dementsprechend macht es manchmal Sinn, auf einige Mittel zu verzichten, wenn es nicht unbedingt nötig ist. In der objektorientierten Programmierung sind dies If-Konstrukte, die besser durch Polymorphie ersetzt werden sollten.
Im folgenden Video werden die Zusammenhänge und Lösungen gut erklärt, sodass ich mir eigene Beispiele spare und lediglich Ergänzungen mache:
Als erste Ergänzung möchte ich anmerken, dass das Beispiel des Vortragenden zwar für das grundsätzliche Verständnis und als Rätsel gut geeignet ist, auch wenn die dargestellte korrekte Lösung für mich direkt die einzige sinnvolle war, die mir einfiel, aber das ist wohl meiner Denkweise geschuldet?
Auf jeden Fall wird es sicher Fälle geben, in denen die Lösung nicht so trivial ist und auch durch Delegation und Mehrfachvererbung (Inheritance by delegation) alles verkompliziert wird.
Das Konzept bleibt aber das selbe und als einfach zu merkende Regeln möchte ich ableiten:
IF-Konstrukte sind in der OO per Polymorphie besser zu lösen und sind in den meisten Fällen "böse". Sie sollten verhindert werden, wann immer möglich, auch wenn dies etwas mehr Denkaufwand bedeutet!
Vergleiche mit Basis-Datentypen dürfen weiterhin per if-Konstrukt erfolgen.
IF-Konstrukte in Factories sind erlaubt, um Schnittstellen zu vereinfachen, sollten aber auch hier wann immer möglich verhindert werden.
Der zunächst übermäßig wirkende Aufwand durch die Polymorphie macht Sinn und zahlt sich in 99% aller Fälle später aus. Das letzte verbleibende Prozent sei der Tatsache geschuldet, dass der Code vielleicht nicht mehr komplexer an dieser Stelle wird, aber die Erfahrung zeigt, dass wir nie glauben sollten, wir könnten dies vorher ausschließen.
IF-Konstrukte, deren Auswirkung nicht permanent in der polymorphen Klasse abgelegt werden sollen, können per Visitor-Pattern direkt dort implementiert werden, wo sonst das IF-Konstrukt stehen würde. Dadurch wird der Code leichter erweiterbar und der Compiler bemerkt, wenn der Visitor aufgrund der Änderung des Interfaces angepasst werden muss.
Ich weiß, wie schwer es teilweise fällt, sich zu überwinden auf IFs zu verzichten, schließlich könnte man so Denkaufwand umgehen und zunächst schneller fertig werden. (Somit höchstens im Protoyping und Rapid Application Development TEMPORÄR erlaubt).
Bei Änderungen, Erweiterungen und dem hinzuziehen anderer Teammitglieder wird sich der Aufwand aber in jedem Code, der länger als eine Präsentation lebt, lohnen!