Les langages OO peuvent être utilisés à la place des langages de bas niveau pour parfois s'interfacer directement avec une machine. C ++ Bien sûr, mais même pour C #, il existe des adaptateurs et autres. Bien qu'il soit préférable d'écrire du code pour contrôler les pièces mécaniques et d'avoir un contrôle minutieux de la mémoire aussi près que possible du niveau le plus bas. Mais si cette question est liée aux logiciels orientés objet actuels tels que Line Of Business, les applications Web, IOT, les services Web et la majorité des applications de masse, alors ...
Réponse, le cas échéant
Les lecteurs peuvent essayer de travailler avec une architecture orientée services (SOA). Autrement dit, DDD, N-Layered, N-Tiered, Hexagonal, que ce soit. Je n'ai pas vu une application de grande entreprise utiliser efficacement les OO (Active-Record ou Rich-Models) "traditionnels" comme cela a été décrit dans les années 70 et 80 au cours de la dernière décennie +. (Voir note 1)
La faute n'est pas à l'OP, mais il y a quelques problèmes avec la question.
L'exemple que vous fournissez est simplement de démontrer le polymorphisme, ce n'est pas du code de production. Parfois, des exemples exactement comme ça sont pris au pied de la lettre.
Dans FP et SOA, les données sont séparées de la logique métier. Autrement dit, les données et la logique ne vont pas ensemble. La logique entre dans les services et les données (modèles de domaine) n'ont pas de comportement polymorphe (voir la note 2).
Les services et fonctions peuvent être polymorphes. Dans FP, vous passez fréquemment des fonctions en tant que paramètres à d'autres fonctions au lieu de valeurs. Vous pouvez faire la même chose dans les langages OO avec des types comme Callable ou Func, mais cela ne fonctionne pas de manière rampante (voir la note 3). Dans FP et SOA, vos modèles ne sont pas polymorphes, seulement vos services / fonctions. (Voir note 4)
Il y a un mauvais cas de codage en dur dans cet exemple. Je ne parle pas seulement de la chaîne de couleur rouge "chien aboie". Je parle également du CatModel et du DogModel eux-mêmes. Que se passe-t-il lorsque vous souhaitez ajouter un mouton? Vous devez entrer dans votre code et créer un nouveau code? Pourquoi? Dans le code de production, je préfère voir juste un AnimalModel avec ses propriétés. Au pire, un AmphibianModel et un FowlModel si leurs propriétés et leur manipulation sont si différentes.
Voici ce que j'attends de voir dans un langage "OO" actuel:
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);
}
}
Comment passez-vous des classes en OO à la programmation fonctionnelle? Comme d'autres l'ont dit; Vous pouvez, mais pas vraiment. Le but de ce qui précède est de démontrer que vous ne devriez même pas utiliser de classes (dans le sens traditionnel du monde) lorsque vous faites Java et C #. Une fois que vous aurez commencé à écrire du code dans une architecture orientée services (DDD, en couches, hiérarchisée, hexagonale, peu importe), vous serez un peu plus près du fonctionnel car vous séparez vos données (modèles de domaine) de vos fonctions logiques (services).
OO Language un pas de plus vers la PF
Vous pouvez même aller un peu plus loin et diviser vos services SOA en deux types.
Facultatif Type de classe 1 : Services communs de mise en œuvre d'interface pour les points d'entrée. Il s'agit de points d'entrée "impurs" qui peuvent faire appel à d'autres fonctionnalités "pures" ou "impures". Cela peut être vos points d'entrée à partir d'une API RESTful.
Facultatif Type de classe 2 : Pure Business Logic Services. Ce sont des classes statiques qui ont une fonctionnalité "pure". Dans FP, "Pure" signifie qu'il n'y a pas d'effets secondaires. Il ne définit explicitement l'état ou la persistance nulle part. (Voir note 5)
Donc, lorsque vous pensez aux classes dans les langages orientés objet, utilisées dans une architecture orientée services, cela profite non seulement à votre code OO, mais il commence à faire en sorte que la programmation fonctionnelle semble très facile à comprendre.
Remarques
Remarque 1 : la conception orientée objet "riche" ou "enregistrement actif" est toujours présente. Il y a BEAUCOUP de code hérité comme celui-là à l'époque où les gens le faisaient correctement il y a une décennie ou plus. La dernière fois que j'ai vu ce type de code (fait correctement), il provenait d'un jeu vidéo Codebase en C ++ où ils contrôlaient précisément la mémoire et avaient un espace très limité. Cela ne veut pas dire que FP et les architectures orientées services sont des bêtes et ne devraient pas considérer le matériel. Mais ils placent la capacité de changer constamment, d'être maintenue, d'avoir des tailles de données variables et d'autres aspects comme priorité. Dans les jeux vidéo et l'IA machine, vous contrôlez très précisément les signaux et les données.
Remarque 2 : les modèles de domaine n'ont pas de comportement polymorphe ni de dépendances externes. Ils sont "isolés". Cela ne signifie pas qu'ils doivent être 100% anémiques. Ils peuvent avoir beaucoup de logique liée à leur construction et à la modification des propriétés mutables, le cas échéant. Voir DDD "Value Objects" et Entités par Eric Evans et Mark Seemann.
Remarque 3 : Linq et Lambda sont très courants. Mais lorsqu'un utilisateur crée une nouvelle fonction, il utilise rarement Func ou Callable comme paramètres, alors que dans FP, il serait bizarre de voir une application sans fonctions suivant ce modèle.
Note 4 : Ne confondez pas le polymorphisme avec l'héritage. Un CatModel peut hériter d'AnimalBase pour déterminer les propriétés d'un animal. Mais comme je le montre, des modèles comme celui-ci sont une odeur de code . Si vous voyez ce modèle, vous pourriez envisager de le décomposer et de le transformer en données.
Remarque 5 : Les fonctions pures peuvent (et acceptent) des fonctions en tant que paramètres. La fonction entrante peut être impure, mais peut être pure. À des fins de test, ce serait toujours pur. Mais en production, bien qu'il soit traité comme pur, il peut contenir des effets secondaires. Cela ne change pas le fait que la fonction pure est pure. Bien que la fonction de paramètre puisse être impure. Pas déroutant! :RÉ