Dependency Inversion in OOP significa che si codifica contro un'interfaccia che viene poi fornita da un'implementazione in un oggetto.
Le lingue che supportano funzioni linguistiche superiori possono spesso risolvere semplici problemi di inversione delle dipendenze passando il comportamento come funzione invece di un oggetto che implementa un'interfaccia in senso OO.
In tali lingue, la firma della funzione può diventare l'interfaccia e viene passata una funzione anziché un oggetto tradizionale per fornire il comportamento desiderato. Il buco nel modello centrale è un buon esempio per questo.
Ti consente di ottenere lo stesso risultato con meno codice e più espressività, poiché non è necessario implementare un'intera classe conforme a un'interfaccia (OOP) per fornire il comportamento desiderato per il chiamante. Invece, puoi semplicemente passare una semplice definizione di funzione. In breve: il codice è spesso più facile da mantenere, più espressivo e più flessibile quando si utilizzano funzioni di ordine superiore.
Un esempio in C #
Approccio tradizionale:
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);
Con funzioni di ordine superiore:
public IEnumerable<Customer> FilterCustomers(Func<Customer, bool> filter, IEnumerable<Customers> customers)
{
foreach(var customer in customers)
{
if(filter(customer))
{
yield return customer;
}
}
}
Ora l'implementazione e l'invocazione diventano meno ingombranti. Non è più necessario fornire un'implementazione IFilter. Non abbiamo più bisogno di implementare classi per i filtri.
var filteredDataByName = FilterCustomers(x => x.Name.Equals("CustomerName"), customers);
var filteredDataByBirthday = FilterCustomers(x => x.Birthday == SomeDateTime, customers);
Naturalmente, questo può già essere fatto da LinQ in C #. Ho appena usato questo esempio per illustrare che è più semplice e flessibile utilizzare funzioni di ordine superiore anziché oggetti che implementano un'interfaccia.