Abhängigkeitsinversion in OOP bedeutet, dass Sie gegen eine Schnittstelle codieren, die dann von einer Implementierung in einem Objekt bereitgestellt wird.
Sprachen, die Funktionen für höhere Sprachen unterstützen, können oft einfache Abhängigkeitsinversionsprobleme lösen, indem sie das Verhalten als Funktion anstelle eines Objekts übergeben, das eine Schnittstelle im OO-Sinne implementiert.
In solchen Sprachen kann die Signatur der Funktion zur Schnittstelle werden, und eine Funktion wird anstelle eines herkömmlichen Objekts übergeben, um das gewünschte Verhalten zu erzielen. Das Loch im mittleren Muster ist dafür ein gutes Beispiel.
Auf diese Weise erzielen Sie dasselbe Ergebnis mit weniger Code und mehr Ausdruckskraft, da Sie keine ganze Klasse implementieren müssen, die einer OOP-Schnittstelle entspricht, um das gewünschte Verhalten für den Aufrufer bereitzustellen. Stattdessen können Sie einfach eine einfache Funktionsdefinition übergeben. Kurz gesagt: Code ist oft einfacher zu pflegen, aussagekräftiger und flexibler, wenn Funktionen höherer Ordnung verwendet werden.
Ein Beispiel in C #
Traditioneller Ansatz:
public IEnumerable<Customer> FilterCustomers(IFilter<Customer> filter, IEnumerable<Customers> customers)
{
foreach(var customer in customers)
{
if(filter.Matches(customer))
{
yield return customer;
}
}
}
//now you've got to implement all these filters
class CustomerNameFilter : IFilter<Customer> /*...*/
class CustomerBirthdayFilter : IFilter<Customer> /*...*/
//the invocation looks like this
var filteredDataByName = FilterCustomers(new CustomerNameFilter("SomeName"), customers);
var filteredDataBybirthDay = FilterCustomers(new CustomerBirthdayFilter(SomeDate), customers);
Mit Funktionen höherer Ordnung:
public IEnumerable<Customer> FilterCustomers(Func<Customer, bool> filter, IEnumerable<Customers> customers)
{
foreach(var customer in customers)
{
if(filter(customer))
{
yield return customer;
}
}
}
Jetzt werden die Implementierung und der Aufruf weniger umständlich. Wir müssen keine IFilter-Implementierung mehr bereitstellen. Wir müssen keine Klassen mehr für die Filter implementieren.
var filteredDataByName = FilterCustomers(x => x.Name.Equals("CustomerName"), customers);
var filteredDataByBirthday = FilterCustomers(x => x.Birthday == SomeDateTime, customers);
Dies kann natürlich bereits von LinQ in C # durchgeführt werden. Ich habe dieses Beispiel nur verwendet, um zu veranschaulichen, dass es einfacher und flexibler ist, Funktionen höherer Ordnung anstelle von Objekten zu verwenden, die eine Schnittstelle implementieren.