2016-07-29 3 views
0

Ich programmiere gerne in einem funktionalen Stil. Aber mir ist in den Sinn gekommen, dass das Übergeben von Funktionen als Argumente manchmal eine stärkere Kopplung zwischen Komponenten erzeugen kann, als sie bei der Übergabe von Nichtfunktionsargumenten erzeugt würde. Zum Beispiel in dem folgenden (gekünstelten) Beispiel: A, B und C sind durch den Ausgabetyp des Funktionsarguments von C, durch den Typ von Cs int-Argument und auch durch den Arity- und Eingabetyp von Cs gekoppelt Funktionsargument Wenn A seine Funktion in eine BiFunktion ändern möchte, müssen sich B und C ändern.Funktionen als Argumente: Starke Kopplung?

public class Functional { 

    public void A() { 
    C(i -> String.valueOf(i + 2), 123); 
    } 

    public void B() { 
    C(i -> String.valueOf(i + 1), 123); 
    } 

    private String C(Function<Integer, String> f, int a) { 
    int len = String.valueOf(a).length(); 
    return f.apply(len); 
    } 
} 

Contrast dies mit einem Beispiel, in dem A und B das Ergebnis der Funktion vorne bis berechnen, passiert dann das String Ergebnis und das zweite int Argument C. Hier A, B und C verbunden sind, nur in zwei Orte - die beiden Argumente von C. Die Funktion zur Berechnung des ersten Arguments kann frei geändert werden.

Offensichtlich vorbei Funktionen hat seinen Platz, aber es scheint, dass diese Art von Problem starre Code Verbindung und schaffen kann, wenn die Dinge komplexer werden. Ich würde gerne irgendwelche Faustregeln hören, die Sie verwenden, um zu entscheiden, ob die Kopplung auf diese Weise in Ordnung ist, im Gegensatz zu nicht.

+1

Das ist eine merkwürdige Überlegung. 1) "* Wenn A seine Funktion in eine BiFunktion * ändern möchte" seit wann kann ein Anrufer entscheiden, den Parametertyp einer Methode zu ändern? 'C' bietet eine Funktionalität und definiert die Voraussetzungen; 'A' muss hier nichts" wollen ". 2) Wenn "C" keine Funktion als Parametertyp benötigt, sollte keine Funktion angefordert werden. Wenn die angebotene Funktionalität es erfordert, dann ist es aus der Diskussion. In Ihrem Beispiel ist es, so wie es erfunden ist, * unmöglich * für die Anrufer, das Ergebnis der Funktion im Voraus zu berechnen. Aber sie konnten * danach *. – Holger

Antwort

3

In Ihrem Beispiel würde ich empfehlen Prinzip der Single Responsibility

Versammeln die Dinge zu folgen, die aus den gleichen Gründen ändern. Trennen Sie die Dinge, die sich aus verschiedenen Gründen ändern.

Die Entscheidung, auf welche Weise A, B mit C gekoppelt werden, hängt davon ab, warum sie sich ändern werden.


Ein weiteres Prinzip, das aus Ihrem Beispiel in den Sinn kommt, ist Rule of least power

eine Auswahl an Lösungen gegeben, der fähig ist, die am wenigsten leistungsfähige Lösung wählen Sie Ihr Problem

in Ihrem vereinfachtes Beispiel für die Lösung Funktion C benötigt keine Funktion als Argument. Diese Funktion kann in A, B Seite aufgerufen werden.

2

Wenn Sie einen einfachen Wert mit einem Funktionsargument zu ersetzen, sind Sie etwas falsch machen. Funktionen sollten nur etwas mit engen Kupplung ersetzt werden, in der Regel eines anwendungsspezifische Interface.