Le lingue OO possono essere utilizzate al posto delle lingue di basso livello a volte per interfacciarsi direttamente con una macchina. C ++ Certamente, ma anche per C # ci sono adattatori e simili. Sebbene la scrittura di codice per controllare parti meccaniche e avere un controllo minuto sulla memoria, è meglio conservarla il più vicino possibile al livello più basso. Ma se questa domanda è correlata agli attuali software orientati agli oggetti come Line Of Business, applicazioni Web, IOT, servizi Web e la maggior parte delle applicazioni di massa, allora ...
Rispondi, se applicabile
I lettori potrebbero provare a lavorare con un'architettura orientata ai servizi (SOA). Cioè, DDD, N-Layered, N-Tiered, Hexagonal, qualunque cosa. Non ho visto un'applicazione per grandi aziende utilizzare in modo efficiente OO "tradizionale" (Active-Record o Rich-Models) come è stato descritto negli anni '70 e '80 molto nell'ultimo decennio +. (Vedi nota 1)
La colpa non è dell'OP, ma ci sono un paio di problemi con la domanda.
L'esempio fornito è semplicemente quello di dimostrare il polimorfismo, non è un codice di produzione. A volte esempi esattamente così vengono presi alla lettera.
In FP e SOA, i dati sono separati dalla logica di business. Cioè, dati e logica non vanno insieme. La logica va in Servizi e i Dati (modelli di dominio) non hanno un comportamento polimorfico (Vedi Nota 2).
I servizi e le funzioni possono essere polimorfici. In FP, si passano spesso funzioni come parametri ad altre funzioni anziché a valori. Puoi fare lo stesso in OO Languages con tipi come Callable o Func, ma non funziona in modo dilagante (Vedi Nota 3). In FP e SOA, i tuoi modelli non sono polimorfici, ma solo i tuoi servizi / funzioni. (Vedi nota 4)
C'è un brutto caso di hardcoding in questo esempio. Non sto solo parlando della stringa di colore rosso "dog barks". Sto anche parlando del CatModel e del DogModel stessi. Cosa succede quando vuoi aggiungere una pecora? Devi andare nel tuo codice e creare un nuovo codice? Perché? Nel codice di produzione, preferirei vedere solo un AnimalModel con le sue proprietà. Nel peggiore dei casi, un AnfibianModel e un FowlModel se le loro proprietà e gestione sono così diverse.
Questo è quello che mi aspetterei di vedere in una lingua "OO" corrente:
public class Animal
{
public int AnimalID { get; set; }
public int LegCount { get; set; }
public string Name { get; set; }
public string WhatISay { get; set; }
}
public class AnimalService : IManageAnimals
{
private IPersistAnimals _animalRepo;
public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }
public List<Animal> GetAnimals() => _animalRepo.GetAnimals();
public string WhatDoISay(Animal animal)
{
if (!string.IsNullOrWhiteSpace(animal.WhatISay))
return animal.WhatISay;
return _animalRepo.GetAnimalNoise(animal.AnimalID);
}
}
Come si passa dalle classi in OO alla programmazione funzionale? Come altri hanno già detto; Puoi, ma non davvero. Il punto di cui sopra è dimostrare che non dovresti nemmeno usare Classi (nel senso tradizionale del mondo) quando fai Java e C #. Una volta che hai iniziato a scrivere codice in un'architettura orientata ai servizi (DDD, Layered, Tiered, Hexagonal, qualunque cosa), sarai un passo avanti verso Functional perché separi i tuoi dati (modelli di dominio) dalle tue funzioni logiche (servizi).
OO Language un passo avanti verso FP
Potresti anche andare un po 'oltre e suddividere i tuoi servizi SOA in due tipi.
Tipo di classe 1 opzionale : Servizi comuni di implementazione dell'interfaccia per punti di ingresso. Si tratterebbe di punti di accesso "impuri" che possono chiamare altre funzionalità "pure" o "impure". Questi potrebbero essere i tuoi punti di ingresso da un'API RESTful.
Tipo di classe 2 opzionale : Servizi di logica aziendale pura. Queste sono classi statiche con funzionalità "Pura". In FP, "Pure" significa che non ci sono effetti collaterali. Non imposta esplicitamente Stato o Persistenza da nessuna parte. (Vedi nota 5)
Pertanto, quando si pensa alle classi in linguaggi orientati agli oggetti, utilizzati in un'architettura orientata ai servizi, non solo avvantaggia il codice OO, ma inizia a far sembrare la programmazione funzionale molto facile da capire.
Gli appunti
Nota 1 : il design orientato agli oggetti "Rich" o "Active-Record" originale è ancora in circolazione. C'è un sacco di codice legacy come quello quando le persone "facevano bene" un decennio o più fa. L'ultima volta che ho visto quel tipo di codice (fatto correttamente) proveniva da un videogioco Codebase in C ++, dove controllavano esattamente la memoria e avevano uno spazio molto limitato. Per non dire che le architetture FP e Service-Oriented sono bestie e non dovrebbero considerare l'hardware. Ma mettono la possibilità di cambiare costantemente, essere mantenuti, avere dimensioni di dati variabili e altri aspetti come priorità. Nei videogiochi e nell'IA artificiale, controlli segnali e dati in modo molto preciso.
Nota 2 : i modelli di dominio non hanno un comportamento polimorfico, né hanno dipendenze esterne. Sono "isolati". Ciò non significa che debbano essere anemici al 100%. Possono avere molte logiche legate alla loro costruzione e all'alterazione della proprietà mutevole, se applicabile. Vedi DDD "Oggetti valore" ed Entità di Eric Evans e Mark Seemann.
Nota 3 : Linq e Lambda sono molto comuni. Ma quando un utente crea una nuova funzione, usa raramente Func o Callable come parametri, mentre in FP sarebbe strano vedere un'app senza funzioni che seguono quel modello.
Nota 4 : non confondere il polimorfismo con l'ereditarietà. Un CatModel potrebbe ereditare AnimalBase per determinare quali Proprietà ha tipicamente un Animale. Ma come mostro, modelli come questo sono un odore di codice . Se vedi questo schema, potresti considerare di scomporlo e trasformarlo in dati.
Nota 5 : le funzioni pure possono (e devono) accettare funzioni come parametri. La funzione in entrata potrebbe essere impura, ma potrebbe essere pura. A scopo di test, sarebbe sempre puro. Ma in produzione, sebbene sia trattato come puro, potrebbe contenere effetti collaterali. Ciò non cambia il fatto che la funzione pura è pura. Sebbene la funzione del parametro possa essere impura. Non confondere! : D