Fermer

juillet 24, 2021

La programmation orientée objet est morte. Attends, vraiment ?



La programmation dans les années 1960 avait un gros problème : les ordinateurs n'étaient pas encore aussi puissants, et d'une manière ou d'une autre, ils devaient répartir les capacités  entre les structures de données et les procédures.

Ceci Cela signifiait que si vous disposiez d'un grand nombre de données, vous ne pouviez pas en faire autant sans pousser un ordinateur à ses limites. D'un autre côté, si vous deviez faire beaucoup de choses, vous ne pouviez pas utiliser trop de données ou l'ordinateur prendrait une éternité.

Puis Alan Kay est arrivéd en 1966 ou 1967 et a théorisé que l'on pouvait utiliser des mini-ordinateurs encapsulés qui ne partageaient pas leurs données, mais communiquaient plutôt par messagerie. De cette façon, les ressources de calcul pourraient être utilisées de manière beaucoup plus économique.

Malgré l'ingéniosité de l'idée, il faudrait jusqu'en 1981  jusqu'à ce que la programmation orientée objet se généralise. Depuis lors, cependant, il n'a cessé d'attirer des développeurs de logiciels nouveaux et chevronnés. Le marché pour les programmeurs orientés objet est plus occupé que jamais.

Mais ces dernières années, le paradigme vieux de dix ans a reçu de plus en plus critique . Se pourrait-il que, quatre décennies après que la programmation orientée objet ait atteint les masses, la technologie dépasse ce paradigme ?

Le couplage de fonctions avec des données est-il si stupide ?

L'idée principale derrière la programmation orientée objet est aussi simple que possible : vous essayez de casser un programme en parties aussi puissantes que l'ensemble. Il s'ensuit que vous couplez des éléments de données et les fonctions qui ne sont utilisées que sur les données en question.

Notez que cela ne couvre que la notion d'encapsulation, c'est-à-dire que les données et les fonctions qui se trouvent à l'intérieur d'un objet sont invisibles de l'extérieur. . On ne peut interagir avec le contenu d'un objet que par le biais de messages, généralement appelés fonctions getter et setter.

Ce qui n'est pas contenu dans l'idée initiale, mais est considéré comme essentiel à la programmation orientée objet aujourd'hui, sont l'héritage et le polymorphisme. L'héritage signifie essentiellement que les développeurs peuvent définir des sous-classes qui ont toutes les propriétés de leur classe parente. Cela n'a été introduit dans la programmation orientée objet qu'en 1976, une décennie après sa conception.

Le polymorphisme est venu à la programmation orientée objet une autre décennie plus tard. En termes simples, cela signifie qu'une méthode ou un objet peut servir de modèle pour d'autres. Dans un sens, il s'agit d'une généralisation de l'héritage, car toutes les propriétés de la méthode ou de l'objet d'origine n'ont pas besoin d'être transmises à la nouvelle entité ; à la place, vous pouvez choisir de remplacer les propriétés.

La particularité du polymorphisme est que même si deux entités dépendent l'une de l'autre dans le code source, une entité appelée fonctionne davantage comme un plugin. Cela facilite la vie des développeurs car ils n'ont pas à se soucier des dépendances lors de l'exécution.

Il convient de mentionner que l'héritage et le polymorphisme ne sont pas exclusifs à la programmation orientée objet. Le véritable différenciateur est l'encapsulation des données et des méthodes qui leur appartiennent. À une époque où les ressources de calcul étaient beaucoup plus rares qu'aujourd'hui, c'était une idée de génie.

Les cinq gros problèmes de la programmation orientée objet

Une fois que la programmation orientée objet a frappé les masses, elle a transformé la façon dont les développeurs voient le code . Ce qui prévalait avant les années 1980, la programmation procédurale, était très orienté machine. Les développeurs devaient en savoir un peu plus sur le fonctionnement des ordinateurs pour écrire un bon code.

En encapsulant les données et les méthodes, la programmation orientée objet a rendu le développement logiciel plus centré sur l'humain. Cela correspond à l'intuition humaine que la méthode drive() appartient au groupe de données carmais pas au groupe ours en peluche .

Lorsque l'héritage est arrivé, c'était aussi intuitif. Il est parfaitement logique que Hyundai est un sous-groupe de voiture et partage les mêmes propriétés, mais PooTheBear[19659026]  ne le fait pas.

Cela ressemble à une machine puissante. Le problème, cependant, est que les programmeurs qui ne connaissent que le code orienté objet forceront cette façon de penser sur tout ce qu'ils font. C'est comme quand les gens voient des clous partout parce qu'ils n'ont qu'un marteau. Comme nous le verrons ci-dessous, lorsque votre boîte à outils ne contient qu'un marteau, cela peut entraîner des problèmes fatals.

Le problème de la jungle des gorilles de la banane

Imaginez que vous configurez un nouveau programme et que vous songez à concevoir un nouvelle classe. Ensuite, vous repensez à une jolie petite classe que vous avez créée pour un autre projet, et vous réalisez qu'elle serait parfaite pour ce que vous essayez de faire actuellement.

Pas de problème ! Vous pouvez réutiliser la classe de l'ancien projet pour votre nouveau.

À l'exception du fait que cette classe peut en fait être une sous-classe d'une autre classe, vous devez donc maintenant inclure la classe parente également. Ensuite, vous réalisez que la classe parent dépend également d'autres classes, et vous finissez par inclure des tas de code.

Le créateur d'Erlang, Joe Armstrong, célèbre  a proclamé :

Le Le problème avec les langages orientés objet est qu'ils ont tout cet environnement implicite qu'ils transportent avec eux. Vous vouliez une banane, mais vous avez obtenu un gorille tenant la banane et toute la jungle.

Cela dit à peu près tout. C'est bien de réutiliser les classes ; en fait, cela peut être une vertu majeure de la programmation orientée objet.

Mais ne le poussez pas à l'extrême. Parfois, vous feriez mieux d'écrire une nouvelle classe au lieu d'inclure des masses de dépendances dans l'intérêt de DRY (ne vous répétez pas).

Le problème de la classe de base fragile

Imaginez que vous ayez réutilisé avec succès une classe d'une autre projet pour votre nouveau code. Que se passe-t-il si la classe de base change ?

Cela peut corrompre l'intégralité de votre code. Vous n'y avez peut-être même pas touché. Mais un jour, votre projet fonctionne à merveille, le lendemain, ce n'est pas le cas parce que quelqu'un a modifié un détail mineur dans la classe de base qui finit par être crucial pour votre projet.

Plus vous utilisez l'héritage, plus vous avez de potentiel de maintenance. devoir faire. Ainsi, même si la réutilisation du code semble très efficace à court terme, cela peut devenir coûteux à long terme.

Le problème du diamant

L'héritage est cette petite chose mignonne où nous pouvons prendre les propriétés d'une classe et les transférer à d'autres . Mais que faire si vous voulez mélanger les propriétés de deux classes différentes ?

Eh bien, vous ne pouvez pas le faire. Du moins pas d'une manière élégante. Considérons par exemple la classe Copier. (J'ai emprunté cet exemple, ainsi que quelques informations sur les problèmes présentés ici, à  histoire virale Au revoir, programmation orientée objet de Charles Scalfani.) Un copieur scanne le contenu de un document et l'imprime sur une feuille vide. Donc, devrait-il s'agir de la sous-classe de  Scannerou de  Printer ?

Il n'y a tout simplement pas de bonne réponse. Et même si ce problème ne va pas casser votre code, il revient assez souvent pour être frustrant.

Le problème de hiérarchie

Dans le problème du diamant, la question était de savoir quelle classe Copier[19659026] est une sous-classe de. Mais je vous ai menti - il y a une bonne solution. Soit  Copier  la classe parent et Scanner et Printer des sous-classes qui n'héritent que d'un sous-ensemble des propriétés. Problème résolu !

C'est bien. Mais que se passe-t-il si votre copieur n'est qu'en noir et blanc et que votre imprimante  peut également gérer la couleur ?  Printer n'est-il pas en ce sens une généralisation de Copier ? Que faire si Imprimante est connecté au WiFi, mais Copieur ne l'est pas ?

Plus vous accumulez de propriétés sur une classe, le il devient plus difficile d'établir des hiérarchies appropriées. En réalité, vous avez affaire à des clusters de propriétés, où Copier  partage certaines, mais pas toutes les propriétés de  Printeret vice versa. Et si vous essayez de coller cela dans des hiérarchies, et que vous avez un gros projet complexe, cela pourrait vous conduire à un désastre désordonné.

Le problème de référence

Vous pourriez dire, d'accord, alors nous allons simplement faire l'objet- programmation orientée sans hiérarchies. Au lieu de cela, nous pourrions utiliser des clusters de propriétés et hériter, étendre ou remplacer les propriétés selon les besoins. Bien sûr, ce serait un peu compliqué, mais ce serait une représentation précise du problème à résoudre.

Il n'y a qu'un seul problème. L'objectif de l'encapsulation est de protéger les données les unes des autres et de rendre ainsi l'informatique plus efficace. Cela ne fonctionne pas sans hiérarchies strictes.

Considérez ce qui se passe si un objet A  outrepasse la hiérarchie en interagissant avec un autre objet B. Peu importe la relation qu'entretient A  avec Bsauf que  B n'est pas la classe parente directe. Ensuite, A doit contenir une référence privée à Bcar sinon, il ne pourrait pas interagir.

Mais si [19659025]A contient les informations que possèdent également les enfants de B ces informations peuvent être modifiées à plusieurs endroits. Par conséquent, les informations sur  B  ne sont plus sûres et l'encapsulation est rompue.

Bien que de nombreux programmeurs orientés objet construisent des programmes avec ce type d'architecture, ce n'est pas le cas. programmation orientée objet. C'est juste un gâchis.

Le danger du paradigme unique

Ce que ces cinq problèmes ont en commun, c'est qu'ils implémentent l'héritage là où ce n'est pas la meilleure solution. Puisque l'héritage n'était même pas inclus dans la forme originale de la programmation orientée objet, je n'appellerais pas ces problèmes inhérents à l'orientation objet. Ce ne sont que des exemples d'un dogme poussé trop loin.

Non seulement la programmation orientée objet peut être exagérée, cependant. En programmation fonctionnelle pure il est extrêmement difficile de traiter les entrées de l'utilisateur ou d'imprimer des messages sur un écran. La programmation orientée objet ou procédurale est bien meilleure à ces fins.

Pourtant, il y a des développeurs qui essaient d'implémenter ces choses comme des fonctions pures et de faire exploser leur code jusqu'à des dizaines de lignes que personne ne peut comprendre. En utilisant un autre paradigme, ils auraient pu facilement réduire leur code à quelques lignes lisibles.

Les paradigmes sont un peu comme les religions. Ils sont bons avec modération – sans doute, Jésus, Mohamed et Bouddha ont dit des trucs plutôt cool. Mais si vous les suivez dans les moindres détails, vous pourriez finir par rendre la vie de vous-même et des personnes autour de vous assez misérable.

Il en va de même pour les paradigmes de programmation. Il ne fait aucun doute que la programmation fonctionnelle   gagne du terrainalors que la programmation orientée objet a suscité certaines critiques sévères  ces dernières années.

Il est logique de s'informer sur les nouveaux paradigmes de programmation et de les utiliser le cas échéant. Si la programmation orientée objet est le marteau qui fait que les développeurs voient des clous partout où ils vont, est-ce une raison pour jeter le marteau par la fenêtre ? Non. Vous ajoutez un tournevis à votre boîte à outils, et peut-être un couteau ou une paire de ciseaux, et vous choisissez votre outil en fonction du problème à résoudre.

Les programmeurs fonctionnels et orientés objet, arrêtez de traiter vos paradigmes comme une religion. . Ce sont des outils, et ils ont tous leur utilité quelque part. Ce que vous utilisez ne devrait dépendre que des problèmes que vous résolvez.

La grande question : sommes-nous à l'aube d'une nouvelle révolution ?

En fin de compte, le débat, certes assez houleux, du fonctionnel contre La programmation orientée objet se résume à ceci : pourrions-nous atteindre la fin de l'ère de la programmation orientée objet ?

De plus en plus de problèmes surgissent là où la programmation fonctionnelle est souvent l'option la plus efficace. Pensez à l'analyse des données, à l'apprentissage automatique et à la programmation parallèle. Plus vous entrez dans ces domaines, plus vous aimerez la programmation fonctionnelle.

Mais si vous regardez le statu quo, il existe une douzaine d'offres pour les programmeurs orientés objet à une offre pour les codeurs fonctionnels. Cela ne veut pas dire que vous n'obtiendrez pas de travail si vous préférez ce dernier ; les développeurs fonctionnels sont encore assez rares de nos jours.

Le scénario le plus probable est que la programmation orientée objet restera en place pendant encore une dizaine d'années. Bien sûr, l'avant-garde est fonctionnelle, mais cela ne signifie pas que vous devriez encore abandonner l'orientation objet. C'est toujours incroyablement bon à avoir dans votre répertoire.

Alors ne jetez pas la programmation orientée objet hors de votre boîte à outils au cours des prochaines années. Mais assurez-vous que ce n'est pas le seul outil dont vous disposez.

Cet article a été écrit par Rhea Moutafis et a été initialement publié sur Towards Data Science. Vous pouvez le lire ici.




Source link