====== Vermeidung von Redundanzen ====== ===== Redundanzen ===== Wenn gleiche Aufgaben im Programm an mehreren Stellen durchgeführt werden, dann kann sich für diese Aufgabe gleich an mehreren Stellen ein Fehler einschleichen. Beim Testen oder Ändern des Quelltextes werden unter Umständen Programmteile übersehen, die diese Aufgabe auch gelegentlich durchführen, kurz: Das Risiko von Fehlern steigt beträchtlich. Entsprechend begrüßenswert wäre eine Unterstützung der Sprache, um redundante Programmteile zu vermeiden. In diesem Kapitel geht es darum, Stellen zu identifizieren und Lösungen anzubieten, um diese Fehlerquellen zu minimieren. ===== Adapter ===== Überladene Funktionen bearbeiten häufig die gleiche Aufgabe und existieren nur in mehrfacher Ausführung, um dem Programmierer häufige Castings oder Typkonvertierungen zu ersparen. Diese werden dann innerhalb der Funktion erledigt. \\ Grade bei kleineren Funktionen wird hier häufig die vollständige Funktion kopiert, um das jeweilige Casting erweitert und schon existiert eine redundante Funktionalität im Quelltext. \\ Man könnte die Funktion aufrufen, aber ein zusätzlicher Funktionsaufruf bedeutet den Aufbau eines zusätzlichen Stacks, sofern die Funktion nicht „inline“ realisiert werden kann. \\ Findet sich derartige Konstrukte rekursiv und/oder in Schleifen, so verlangsamt sich die Ausführung. \\ Weiterhin beginnt vielen überladenen Funktionen regelmäßig die Suche nach der Funktion, die die eigentliche Funktionalität beinhaltet. \\ Aus diesem Grund definiere ich hier einen neuen Funktionstyp, der eher in Kooperation mit einer normalen Funktion arbeitet: den Adapter. \\ Die Funktion verlangt genau die Datentypen, die sie zur Bearbeitung benötigt werden. \\ Soll die Funktion mit anderen Datentypen gerufen werden, die zunächst noch konvertiert werden müssen oder Datenbankzugriffe erfordern oder ähnliches, so wird ein Adapter formuliert. \\ Er initialisiert den Stack und konvertiert die benötigten Daten in die für die Funktion passenden Datentypen. Anschließend setzt er die Ausführung in der eigentlichen Funktion fort, die nach getaner Arbeit zurück zur Adapter aufrufenden Funktion zurückkehrt. \\ Der Sprung von Adapter zur Funktion wird also nicht durch ein Unterprogramm gelöst, sondern durch einen direkten Sprung: Genesys-Sourcecode code( neutral, string text ) ausgabe: print text; adapter( neutral; int zahl ) ausgabe: { // beliebige Vorbereitung continue ausgabe( $zahl ); // Konvertierung als String } Hier ist klar erkennbar, welche Funktion die Funktionalität beinhaltet und welche ausschließlich als Adapter vor der Funktionalität ausgeführt wird.