Inversione di dipendenza in OOP significa che si codifica su un'interfaccia che viene quindi fornita da un'implementazione in un oggetto.
Le lingue che supportano funzioni linguistiche più elevate possono spesso risolvere semplici problemi di inversione di dipendenza trasmettendo il comportamento come funzione anziché come oggetto che implementa un'interfaccia in senso OO.
In tali lingue, la firma della funzione può diventare l'interfaccia e una funzione viene passata al posto di 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à, in quanto 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 usano 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 di IFilter. Non abbiamo più bisogno di implementare le classi per i filtri.
var filteredDataByName = FilterCustomers(x => x.Name.Equals("CustomerName"), customers);
var filteredDataByBirthday = FilterCustomers(x => x.Birthday == SomeDateTime, customers);
Naturalmente, questo può essere già 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.