Pourquoi n'y a-t-il pas de définition cohérente des concepts essentiels de la POO?

12

Je suis très nouveau dans la programmation et un peu confus en lisant \ en entendant différentes conventions de différentes sources:

La programmation orientée objet a-t-elle 4 ou 5 concepts?

En tant que nouveau venu, je comprends que ce sont les 5 concepts:

  • Abstraction
  • Héritage
  • Encapsulation
  • Polymorphisme
  • Modularité

Alors comment se fait-il que je ne trouve pas de définition plus "stricte" et qu'il semble y avoir plusieurs arrangements de ces concepts là-bas?


la source
7
Peut-être parce que ce n'est pas comme les mathématiques (certains concepts en CS le sont, mais je pense que la POO n'appartient pas à cette catégorie), donc il n'y a pas de définitions strictes pour commencer. Par exemple, quelle est l'importance de la «modularité»? Est-ce vraiment si spécial pour la POO que nous devons le mentionner ou serait-ce juste quelque chose qui se produit tout seul si nous appliquons correctement les quatre autres? Certaines listes ajoutent une «hiérarchie», mais est-ce vraiment quelque chose d'extra ou découle simplement de l'héritage et du polymorphisme?
thorsten müller
6
Un conseil: en tant que tout nouveau programmeur, vous ne devriez pas vous accrocher à la compréhension de la terminologie et de la théorie. Rassemblez d'abord une expérience de programmation pratique, et il deviendra beaucoup plus évident de quoi ces gens parlent.
Philipp
9
Une autre chose est que la POO change avec le temps. Dans les premiers jours du C ++ (je sais que la POO remonte plus loin que cela), l'accent était mis sur l'héritage et le polymorphisme. Aujourd'hui, l'accent est beaucoup plus mis sur l'abstraction et l'encapsulation.
Bent
3
Une discussion intéressante sur le manque de précision dans la définition de l'OO peut être trouvée ici: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Réponses:

26

La raison pour laquelle vous trouvez des explications différentes de ce que signifie la programmation orientée objet est qu'il n'y a pas une seule personne ou organisation ayant le pouvoir de formuler une définition stricte universellement applicable.

La programmation orientée objet n'est pas une norme ISO ni une loi scientifique. C'est une philosophie. Et comme pour toutes les philosophies, il existe toutes sortes d'interprétations différentes et aucune interprétation n'est universellement applicable. Lorsque vous lisez un texte qui vous dit quels concepts vous devez suivre lors de la conception d'une architecture logicielle, vous devez le voir comme une ligne directrice basée sur les opinions que l'auteur a formulées au cours de son expérience professionnelle, et non comme une vérité universelle.

Philipp
la source
12

La programmation orientée objet a-t-elle 5 ou 4 composants?

Comme d'autres l'ont mentionné, "OO" n'a pas vraiment de composants , car c'est une façon de penser à la modélisation des solutions aux problèmes et non une boîte à outils ni un ensemble de processus clairement définis.

En tant que nouveau venu, je comprends que ce sont les 5 composants:

Abstraction, héritage, encapsulation, polymorphisme et modularité?

L'héritage et le polymorphisme sont des fonctionnalités du langage de programmation. Il est bon que vous les compreniez, mais rappelez-vous que ce sont des outils (ce qui signifie que, comme pour tout autre outil, ils ne doivent être utilisés que pour résoudre des problèmes spécifiques, et non traités comme un objectif ou quelque chose vers lequel tendre). Vous pouvez (et devez souvent) écrire du code "OO" sans utiliser l'un ou l'autre. Certains des meilleurs codes "OO" que j'ai jamais vus utilisent très peu l'héritage ou le polymorphisme.

L'abstraction, l'encapsulation et la modularité ont moins à voir avec le code et plus avec la façon dont vous regardez un problème, la façon dont vous essayez de comprendre ce problème et la façon dont vous concevez et structurez votre solution en code.

De plus, ces idées de conception ne sont pas exclusives à "OO". Il y a de fortes chances que vous les compreniez probablement maintenant au niveau de base, ce qui pourrait inclure la possibilité d'expliquer une définition parfaite du manuel et de les appliquer à des problèmes quelque peu banals; bien qu'un test plus approfondi de compréhension soit donné à un très grand problème complexe et à la complexité que vous pouvez gérer.

Un autre test de compréhension est l'approche que vous utilisez pour résoudre un problème; et les nouveaux arrivants à "OO", qui sont souvent enseignés sur OO en termes de modélisation des données (parce que c'est ainsi que la plupart des gens le comprenaient dans les années 1990), et finissent souvent par se concentrer sur les mauvais aspects d'un problème - c'est-à-dire qu'ils se concentrent trop sur les données, et ils ne se concentrent pas assez sur le comportement.

Par exemple, des exemples classiques font souvent référence à des entités telles que Dog, Cat, Elephant, Seagull, Shark, etc. Les nouveaux arrivants à « OO » regarde souvent ces exemples et je pense immédiatement « Oh, j'ai besoin d' une entité de base appelée Animal» , et ils peuvent même se retrouver avec d' autres des entités intermédiaires telles que Mammalet Amphibiandans une hiérarchie d'héritage soignée, avec des attributs différents dans chacune.

Bien que cette façon de penser démontre une compréhension très basique de plusieurs concepts OO, un programmeur OO expérimenté ne l'aborderait jamais comme ça ni ne sauterait à cette conclusion (et se plaindrait en fait de ne pas avoir suffisamment d'informations), car cette approche démontre l'entité la modélisation plutôt que la modélisation OO, et parce que l'exemple artificiel ne dit rien sur le comportement de ces animaux (Et beaucoup de gens diraient ces jours-ci que l' essence de l'OO est tout dans le comportement et la fonctionnalité).

Le chemin vers l'apprentissage de "OO" implique traditionnellement de passer du temps à construire les mauvaises abstractions lorsque vous ne savez rien (ou trop peu) sur le comportement du problème que vous modélisez, ou lorsque vous faites l'erreur de concentrer votre attention sur les entités plutôt que fonctionnalité, même si cela tient en partie au fait que tant de livres, de cours et de didacticiels en ligne écrits au fil des ans ont (mal) guidé les apprenants sur cette voie depuis longtemps (La marée change cependant).

Dans l'ensemble, une grande partie de votre compréhension se résumera à l'expérience. Ces concepts que vous avez appris jusqu'à présent sont un bon début, il y a d'autres concepts que vous devrez apprendre en cours de route (par exemple, les principes "SOLIDE" et "SEC"), et vous devrez passer beaucoup de temps à mettre la théorie dans la pratique avec de vrais problèmes très complexes avant que tout ne soit susceptible de "cliquer" en place.

Ben Cottrell
la source
2
Un requin et une grenouille nagent tous les deux, mais l'un est un poisson, l'autre est un amphibien. Je pense que cet exemple décrit bien votre point.
RubberDuck
10

Le terme "Object-Orientation" a été inventé par le Dr Alan Kay, il est donc la source faisant autorité sur ce qu'il signifie, et il le définit ainsi :

Pour moi, la POO signifie uniquement la messagerie, la conservation et la protection locales et la dissimulation du processus étatique, et la liaison tardive extrême de toutes choses.

Décomposons cela:

  • messagerie ("envoi de méthode virtuelle", si vous n'êtes pas familier avec Smalltalk)
  • le processus d'état doit être
    • conservé localement
    • protégé
    • caché
  • liaison tardive extrême de toutes choses

En ce qui concerne l'implémentation, la messagerie est un appel de procédure à liaison tardive, et si les appels de procédure sont à liaison tardive, vous ne pouvez pas savoir au moment de la conception ce que vous allez appeler, vous ne pouvez donc pas faire d'hypothèses sur la représentation concrète de l'état. Donc, il s'agit vraiment de messagerie, la liaison tardive est une implémentation de la messagerie et l'encapsulation en est la conséquence.

Il a ensuite précisé que " la grande idée est la" messagerie " ", et regrette de l'avoir appelé "orienté objet" au lieu de "orienté message", car le terme "orienté objet" met l'accent sur la chose sans importance (objets ) et détourne l'attention de ce qui est vraiment important (messagerie):

Juste un petit rappel que j'ai pris la peine lors du dernier OOPSLA pour essayer de rappeler à tout le monde que Smalltalk n'est pas seulement PAS sa syntaxe ou la bibliothèque de classes, il ne s'agit même pas de classes. Je suis désolé d'avoir inventé il y a longtemps le terme «objets» pour ce sujet, car cela amène beaucoup de gens à se concentrer sur l'idée la moins importante.

La grande idée est la «messagerie» - c'est de cela que parle le noyau de Smalltalk / Squeak (et c'est quelque chose qui n'a jamais été complètement terminé dans notre phase Xerox PARC). Les Japonais ont un petit mot - ma - pour «ce qui est entre» - peut-être que l'équivalent anglais le plus proche est «interstitiel». La clé pour créer de grands systèmes évolutifs est beaucoup plus de concevoir la façon dont ses modules communiquent plutôt que ce que devraient être leurs propriétés et comportements internes. Pensez à Internet - pour vivre, il (a) doit permettre de nombreux types d'idées et de réalisations qui vont au-delà d'une norme unique et (b) permettre divers degrés d'interopérabilité sûre entre ces idées.

(Bien sûr, aujourd'hui, la plupart des gens ne se concentrent même pas sur les objets mais sur les classes, ce qui est encore plus faux.)

La messagerie est fondamentale pour l'OO, à la fois comme métaphore et comme mécanisme.

Si vous envoyez un message à quelqu'un, vous ne savez pas ce qu'il en fait. La seule chose que vous pouvez observer, c'est leur réponse. Vous ne savez pas s'ils ont traité le message eux-mêmes (c'est-à-dire si l'objet a une méthode), s'ils ont transmis le message à quelqu'un d'autre (délégation / mandataire), s'ils l'ont même compris. C'est à cela que sert l'encapsulation, c'est à cela que sert OO. Vous ne pouvez même pas distinguer un proxy de la réalité, tant qu'il répond à la façon dont vous vous y attendez.

Un terme plus "moderne" pour "messagerie" est "envoi de méthode dynamique" ou "appel de méthode virtuelle", mais qui perd la métaphore et se concentre sur le mécanisme.

Donc, il y a deux façons de regarder la définition d'Alan Kay: si vous la regardez seule, vous pouvez observer que la messagerie est essentiellement un appel de procédure à liaison tardive et que la liaison tardive implique l'encapsulation, nous pouvons donc conclure que # 1 et # 2 sont en fait redondants, et OO est une liaison tardive.

Cependant, il a précisé plus tard que l'important est la messagerie, et nous pouvons donc le voir sous un angle différent: la messagerie est liée tardivement. Maintenant, si la messagerie était la seule chose possible, alors # 3 serait trivialement vrai: s'il n'y a qu'une seule chose, et que cette chose est liée tardivement, alors toutes les choses sont liées tardivement. Et encore une fois, l'encapsulation découle de la messagerie.

Des points similaires sont également soulignés dans On Understanding Data Abstraction, Revisited by William R. Cook et également sa Proposition de définitions modernes et simplifiées de "Object" et "Object Oriented" .

La répartition dynamique des opérations est la caractéristique essentielle des objets. Cela signifie que l'opération à invoquer est une propriété dynamique de l'objet lui-même. Les opérations ne peuvent pas être identifiées statiquement, et il n'y a aucun moyen en général de savoir exactement quelle opération sera exécutée en réponse à une demande donnée, sauf en l'exécutant. C'est exactement la même chose qu'avec les fonctions de première classe, qui sont toujours distribuées dynamiquement.

Dans Smalltalk-72, il n'y avait même pas d'objets! Il n'y avait que des flux de messages qui ont été analysés, réécrits et redirigés. Les premières méthodes sont arrivées (méthodes standard pour analyser et rediriger les flux de messages), puis les objets (regroupements de méthodes qui partagent un certain état privé). L'héritage est venu beaucoup plus tard et les classes n'ont été introduites que comme moyen de prendre en charge l'héritage. Si le groupe de recherche de Kay connaissait déjà les prototypes, ils n'auraient probablement jamais introduit de cours en premier lieu.

Benjamin Pierce dans Types et langages de programmation fait valoir que la caractéristique qui définit l'Object-Orientation est la récursivité ouverte .

Donc: selon Alan Kay, OO est une question de messagerie. Selon William Cook, OO est tout au sujet de la répartition dynamique des méthodes (ce qui est vraiment la même chose). Selon Benjamin Pierce, OO est tout au sujet de la récursivité ouverte, ce qui signifie essentiellement que les auto-références sont résolues dynamiquement (ou du moins c'est une façon de penser), ou, en d'autres termes, la messagerie.

Comme vous pouvez le voir, la personne qui a inventé le terme "OO" a une vue plutôt métaphysique sur les objets, Cook a une vue plutôt pragmatique et Pierce une vue mathématique très rigoureuse. Mais l'important est: le philosophe, le pragmatiste et le théoricien sont tous d'accord! La messagerie est le seul pilier d'OO. Période.

Notez qu'il n'y a aucune mention d'héritage ici! L'héritage n'est pas essentiel pour l'OO. En général, la plupart des langages OO ont un moyen de réutilisation de l'implémentation, mais cela ne doit pas nécessairement être un héritage. Il pourrait également s'agir d'une forme de délégation, par exemple. En fait, le traité d'Orlando discute de la délégation comme alternative à l'héritage et comment différentes formes de délégation et d'héritage conduisent à différents points de conception dans l'espace de conception des langages orientés objet. (Notez qu'en fait, même dans les langages qui prennent en charge l'héritage, comme Java, les gens apprennent à l'éviter, ce qui indique encore une fois que ce n'est pas nécessaire pour l'OO.)

Jörg W Mittag
la source
1
@DavidArno Votre commentaire n'est pas du tout constructif. Alan Kay lui-même prétend avoir inventé le terme «objet» pour ce concept (bien que, je suppose, pas le concept lui-même). Si vous allez contredire une autorité bien connue sur le sujet, écrivez au moins un commentaire plus constructif.
Andres F.
1
@DavidArno Est-ce que le downvote est aussi le vôtre? Quelqu'un a donc pris le temps d'écrire une liste complète des différents points de vue, d'experts bien connus, sur ce que signifie la POO, et vous l'avez rejeté parce que vous n'êtes pas d'accord avec une seule phrase? Ouais.
Andres F.
2
@AndresF. Cette réponse peut être résumée comme "il y a deux écoles de bien, celle d'Alan Kay et celle de tous les autres. Parce que le premier a inventé le terme qu'il a automatiquement raison et que tous ceux qui ne sont pas d'accord avec lui ont tort". C'est un appel à la réponse erronée de l'autorité. D'où le downvote.
David Arno
2
En fait, cette réponse peut être résumée comme "il y a trois écoles de pensée, venant de trois angles complètement différents et personne n'est en désaccord avec personne, en fait, ils sont tous d'accord." Le prescriptiviste linguistique dirait, Alan Kay a inventé le terme, il arrive à dire ce qu'il signifie, et il dit que cela signifie la messagerie. Le descriptiviste linguistique dirait non, Alan Kay n'a rien à dire, nous devons regarder comment le terme est réellement utilisé , et c'est ce que Cook a fait: il a étudié les langages qui sont communément décrits comme OO (Java, C ++ , C #, etc.) ont en commun, et il a trouvé
Jörg W Mittag
3
Une chose: la messagerie. Il a étudié les langues communément décrites comme non OO qui manquent que les langues communément décrites comme OO ont, et il a trouvé une chose: la messagerie. Le théoricien de la tour d'ivoire prend le λ-calcul et examine ce que le plus petit ensemble de fonctionnalités est qu'il faudrait ajouter pour obtenir quelque chose qui est communément appelé OO, et il arrive à la récursivité ouverte , qui est fondamentalement la pierre angulaire de la messagerie .
Jörg W Mittag
3

Comme l'indique @Philipp, la racine du problème est qu'il n'y a pas de définition officielle de ce qui rend un langage de programmation orienté objet. En effet, c'est probablement une bonne chose. Il existe de nombreuses façons de prendre en charge la programmation OO, chacune avec ses propres avantages et inconvénients. La discussion sur les langues qui sont plus "pure OO" ne fait pas grand-chose.

Cependant, en regardant les 5 attributs que vous avez énumérés, à mon avis, la modularité est certainement la plus étrange. La modularité est vraiment un attribut d'un programme et non un langage de programmation. Au niveau linguistique, l'attribut est "prise en charge de la modularisation", et cela prend généralement la forme d'un mécanisme "modules" pr "packages".

Mais ma véritable objection à la modularité est qu'elle n'est pas la clé de la programmation OO ou des langages de programmation OO, dans la mesure où le langage de programmation archétypal Smalltalk-80 ne supportait pas du tout les modules. Et quand on y pense, la prise en charge linguistique des modules dans de nombreux OOPL largement utilisés est "faible".

Les modules sont conçus pour prendre en charge la «programmation à grande échelle» ... où votre base de code devient trop volumineuse pour qu'une seule personne puisse la comprendre pleinement. Et vous n'avez pas besoin de modules dans un langage de programmation pour modulariser votre code.


Je ne suis pas entré dans le débat sur les 4 autres attributs, et si (par exemple) quels modèles d '"héritage" sont OO purs. De plus, même si Alan Kay est réputé avoir inventé la programmation OO, cela ne signifie pas nécessairement que ses définitions de OO / et OOPL ont la primauté. De toute évidence, ce n'est pas le cas. Il est une source faisant autorité, mais il existe d'autres sources qui donnent d'autres définitions des OO et des OOPL qui (en pratique) ont plus de poids.

Stephen C
la source
2
+1 La modularité est en fait largement acceptée comme un attribut souhaitable de la plupart des systèmes logiciels, quels que soient le langage de programmation et le paradigme utilisés. De nombreuses langues qui ne sont pas OO prennent en charge la modularisation.
Andres F.
+1 @AndresF. commentaire. En effet, la "programmation structurée" et le "raffinement par étapes" (une technique pour penser la structure du code) sort du creuset de "la complexité croissante résultant en un logiciel encore pire". Si elle avait précédé COBOL, la langue n'aurait pas une telle réputation négative à mon humble avis. Et je considère OO de manière pragmatique comme une structure simplement d'ordre supérieur. Et je veux dire que sans structure sous-jacente OO n'est pas mieux que le pire COBOL.
radarbob