L'inversion de dépendance dans la POO signifie que vous codez contre une interface qui est ensuite fournie par une implémentation dans un objet.
Les langages prenant en charge des fonctions de langage supérieures peuvent souvent résoudre des problèmes simples d'inversion de dépendance en transmettant le comportement comme une fonction au lieu d'un objet qui implémente une interface dans le sens OO.
Dans de tels langages, la signature de la fonction peut devenir l'interface et une fonction est transmise à la place d'un objet traditionnel pour fournir le comportement souhaité. Le trou au milieu est un bon exemple de cela.
Cela vous permet d'obtenir le même résultat avec moins de code et plus d'expression, car vous n'avez pas besoin d'implémenter une classe entière conforme à une interface (OOP) pour fournir le comportement souhaité à l'appelant. Au lieu de cela, vous pouvez simplement passer une définition de fonction simple. En bref: le code est souvent plus facile à maintenir, plus expressif et plus flexible lorsque l’on utilise des fonctions d’ordre supérieur.
Un exemple en C #
Approche traditionnelle:
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);
Avec des fonctions d'ordre supérieur:
public IEnumerable<Customer> FilterCustomers(Func<Customer, bool> filter, IEnumerable<Customers> customers)
{
foreach(var customer in customers)
{
if(filter(customer))
{
yield return customer;
}
}
}
Maintenant, l'implémentation et l'invocation deviennent moins lourdes. Nous n'avons plus besoin de fournir une implémentation IFilter. Nous n'avons plus besoin d'implémenter des classes pour les filtres.
var filteredDataByName = FilterCustomers(x => x.Name.Equals("CustomerName"), customers);
var filteredDataByBirthday = FilterCustomers(x => x.Birthday == SomeDateTime, customers);
Bien sûr, cela peut déjà être fait par LinQ en C #. Je viens d'utiliser cet exemple pour illustrer le fait qu'il est plus facile et plus flexible d'utiliser des fonctions d'ordre supérieur au lieu d'objets implémentant une interface.