Funktionen, die Funktionen zurückgeben, die Funktionen …

Posted by in clean code, funktionale Programmierung, funktionales Programmieren, JavaScript

Als ich mich das erste Mal mit funktionaler Programmierung beschäftigt habe, war mir überhaupt nicht klar, wo mir diese ganzen exotischen Konzepte nützen könnten. Inzwischen habe ich viel über dieses Paradigma gelernt und bei manchen Denkansätzen gab es einen richtigen AHA-Effekt.

Ein interessanter Einsatz von Funktionen als Objekte liegt in Funktionen, die Funktionen generieren. Damit kann man sehr interessante Dinge anstellen. Genau das habe ich vor ein paar Wochen getan. Von der Lösung war ich richtig begeistert, die damit so einfach entstanden ist. Diese Begeisterung möchte ich gerne teilen!

Das Problem

In einem Stück Software habe ich die Anforderung, dass ich eine Funktion brauche, die ein oder mehrere DOM-Elemente mit einer bestimmten Klasse versieht. Dummerweise soll zu Programmstart der Name der Klasse festgelegt werden, da er über eine Datei gesteuert wird (Property).

Die einfache Lösung

Für diese Anforderung könnte man folgende Funktion erstellen (Achtung fieser sinnloser Beispielcode):

Für kleine Anwendungsfälle eine mögliche Lösung. Es gibt damit nur zwei Probleme:

  • Die if/else if-Abfrage wird immer länger bei steigender Anzahl der möglichen Klassen und bei jedem Aufuf wird eventuell sinnlos Rechenzeit verbraten
  • Bei jedem Aufruf muss der Name der Property mitgegeben werden. Das heißt entweder eine globale Variable einzuführen oder sie anderweitig verfügbar zu halten an den Stellen, wo sie gebraucht wird

Eine funktionale Lösung

Im Grund genommen ist unsere Anforderung mit einer einzelnen Funktion lösbar, wenn wir nur die übergebene Property irgendwie in der Funktion festtackern könnten beim ersten Aufruf.

Mit funktionaler Programmierung ist das möglich! Dafür erstellen wir eine Funktion makeAddClass die eine Funktion zurückgibt. Im Rumpf jedes if/else if-Blocks steht dann ein return-Statement, das eine Funktion zurückgibt. Das sieht dann so aus:

Hier wird bei Übergabe des Parameters foo eine Funktion zurückgegeben, die die Klasse foo_style. Gleiches Prinzip gilt für bar und die Klasse bar_style.

Wo genau liegt den jetzt der Vorteil dieser Lösung:

  • Als Rückgabewert bekommt man eine Funktion ohne Eingabeparameter, die man einfach immer wieder aufrufen kann ohne die Kenntnis der Property vom Programmstart

  • Es gibt keinen Overhead mehr, da die Entscheidung, was künftig beim Aufruf von addClassFunc passieren soll, nur einmal bei deren Generierung getroffen werden muss

  • Die zurückgegebene Funktion ist so generisch, dass sie jederzeit – auch während der Ausführung des Programms – ausgetauscht werden kann, ohne den Code, der sie aufruft, zu ändern

Fazit

Hat man erst einmal ein Problem mit einer Funktion die eine andere Funktion generiert gefunden und gelöst, dann tut sich eine neue Welt auf. Mir geht es inzwischen so, dass ich immer mehr Anwendungsfälle finde, in denen ich Funktionen generieren kann, anstatt immer wieder die gleiche Logik auszuführen.

Als Nebeneffekt erreicht man auch eine gewisse Unabhängigkeit zum Code der die generierte Funktion verwendet, wie im obigen Beispiel sichtbar wurde.

Wer mit dem Beispiel herumspielen möchte, der kann das in dieser JSBin tun.