La POO est-elle difficile parce que ce n'est pas naturel?


86

On entend souvent que la POO correspond naturellement à la façon dont les gens perçoivent le monde. Mais je suis tout à fait en désaccord avec cette affirmation: nous (ou du moins je) conceptualisons le monde en termes de relations entre les choses que nous rencontrons, mais l'objectif de la programmation orientée objet est de concevoir des classes individuelles et leurs hiérarchies.

Notez que, dans la vie quotidienne, les relations et les actions existent principalement entre des objets qui auraient été des instances de classes non liées dans la POO. Des exemples de telles relations sont: "mon écran est au-dessus de la table"; "Je (un être humain) est assis sur une chaise"; "une voiture est sur la route"; "Je tape sur le clavier"; "la machine à café fait bouillir de l'eau", "le texte est affiché dans la fenêtre du terminal."

Nous pensons en termes de verbes bivalents (parfois trivalents, comme par exemple dans "je vous ai donné des fleurs") où le verbe est l'action (relation) qui agit sur deux objets pour produire un résultat / action. L' accent est mis sur l'action et les deux (ou trois) objets [grammaticaux] ont la même importance.

Comparez cela à la POO où vous devez d’abord trouver un objet (nom) et lui dire d’exécuter une action sur un autre objet. La façon de penser passe des actions / verbes opérant sur les noms à des noms opérant sur des noms - c'est comme si tout était dit à la voix passive ou réfléchie, par exemple, "le texte est affiché par la fenêtre du terminal". Ou peut-être "le texte se dessine sur la fenêtre du terminal".

Non seulement l'attention est déplacée vers les noms, mais l'un des noms (appelons-le sujet grammatical) a une "importance" supérieure à l'autre (objet grammatical). Ainsi, il faut décider si on va dire terminalWindow.show (someText) ou someText.show (terminalWindow). Mais pourquoi encombrer les gens de décisions aussi triviales sans conséquences opérationnelles alors qu’on entend vraiment montrer (terminalWindow, someText)? [Les conséquences sont insignifiantes sur le plan opérationnel - dans les deux cas, le texte est affiché sur la fenêtre du terminal - mais peuvent être très sérieuses dans la conception des hiérarchies de classes et un "mauvais" choix peut conduire à un code compliqué et difficile à maintenir.]

Je dirais donc que la façon habituelle de faire de la programmation orientée objet (classe unique, envoi unique) est difficile car elle n’EST PAS NATURELLE et ne correspond pas à la façon dont les humains perçoivent le monde. Les méthodes génériques de CLOS sont plus proches de ma façon de penser, mais hélas, cette approche n’est pas généralisée.

Compte tenu de ces problèmes, comment et pourquoi est-il arrivé que la manière traditionnelle de faire de la programmation orientée objet soit devenue si populaire? Et que peut-on faire, le cas échéant, pour le détrôner?


La programmation orientée objet est pour la «programmation», elle est faite pour les compilateurs. ce n'est pas une façon de modéliser le monde réel en aucune façon. Il est courant d’utiliser des exemples du monde réel tels que la classe animal et la classe rectangle lors de l’enseignement de la programmation orientée objet, mais il ne s’agit que d’exemples pour simplifier les concepts. Malheureusement, le langage de programmation et les paradigmes «se produisent» de manière non évolutive et non scientifique. À quelques exceptions près, le processus de conception du langage est généralement l’enfant de la meilleure supposition!
NoChance

3
Je ne suis pas d'accord avec l'affirmation selon laquelle "l'objectif premier de la programmation orientée objet est la conception de classes individuelles et de leurs hiérarchies". depuis maybie, il est au centre de certaines mises en œuvre de la POO, mais j’ai par exemple constaté que les langages de POO dynamiques n’avaient généralement pas de grandes hiérarchies, ni même de classes. Eh bien, la définition de la POO pourrait changer à l'avenir, il y a une tentative de changer même l'objet un wcook.blogspot.com/2012/07/proposal-for-simplified-modern.html
vendredi

1
La POO identifie des objets dans le système et construit des classes basées sur ces objets. Pas l'inverse. C'est pourquoi je ne suis pas d'accord non plus avec "l'objectif de la programmation orientée objet est la conception de classes individuelles et de leurs hiérarchies".
Radu Murzea


1
Je pense qu’il s’agit d’une question hautement subjective et qui regorge d’hypothèses étranges au sujet de la programmation orientée objet, du "monde réel" et de la façon dont les gens envisagent les problèmes. Et finalement, il demande même "Et que peut-on faire, le cas échéant, pour le détrôner?" ce qui montre vraiment que le PO a une très forte opinion à ce sujet. Si vous êtes un "religieux" au sujet des paradigmes de programmation, je suppose que vous n'avez pas besoin de réponses ... vous savez déjà ce que vous voulez entendre. Si j'avais eu connaissance de cette question quand elle a été posée pour la première fois, j'aurais probablement voté pour la fermer ...
Simon Lehmann

Réponses:


97

La POO n'est pas naturelle pour certains problèmes. Donc, c'est procédural. Donc, c'est fonctionnel. Je pense que la POO a deux problèmes qui le rendent vraiment difficile.

  1. Certaines personnes agissent comme si c'était la seule façon de programmer et que tous les autres paradigmes étaient faux. IMHO tout le monde devrait utiliser un langage multiparadigm et choisir le meilleur paradigme pour le sous-problème sur lequel ils travaillent actuellement. Certaines parties de votre code auront un style OO. Certains seront fonctionnels. Certains auront un style procédural direct. Avec l'expérience, il devient évident quel paradigme convient le mieux à quoi:

    une. OO est généralement préférable lorsque vous avez des comportements fortement liés à l'état sur lequel ils opèrent, et que la nature exacte de l'état est un détail de mise en œuvre, mais son existence ne peut pas être facilement résumée. Exemple: classes de collections.

    b. La procédure est préférable pour les comportements qui ne sont pas fortement couplés à des données particulières. Par exemple, ils fonctionnent peut-être sur des types de données primitifs. Il est plus facile de penser que le comportement et les données sont des entités distinctes ici. Exemple: code numérique.

    c. Fonctionnel est préférable lorsque vous avez quelque chose d'assez facile à écrire de manière déclarative, de telle sorte que l'existence de n'importe quel état est un détail de mise en œuvre qui peut être facilement résumé. Exemple: mapper / réduire le parallélisme.

  2. OOP montre généralement son utilité sur les grands projets où il est vraiment nécessaire d'avoir des morceaux de code bien encapsulés. Cela n'arrive pas trop dans les projets pour débutants.


4
Je pense qu'un point important dans la question n'était pas de savoir si la POO est naturelle, mais si l'approche traditionnelle de la POO est l'approche la plus naturelle. (Bonne réponse quand même.)
Giorgio

11
"OOP montre généralement son utilité dans les grands projets où il est vraiment nécessaire d'avoir des morceaux de code bien encapsulés.": Mais ce n'est pas une propriété spécifique de OOP, car il existe de bons concepts de modules, y compris pour les langages de programmation impératifs, fonctionnels, ... .
Giorgio

2
OOP est vraiment sur un axe différent de procédural / fonctionnel; il aborde comment organiser et encapsuler le code, pas comment décrire les opérations. (Vous associez toujours OOP à un paradigme d'exécution. Oui, il existe des langages fonctionnels OOP +.)
Donal Fellows

1
Ne pourrait-on pas dire que la POO n'est que les boîtes dans lesquelles nous avons mis les éléments de procédure?
Erik Reppen

En POO, vous pouvez toujours écrire des méthodes. Qu'est-ce qui rend la programmation orientée objet plus faible que la programmation procédurale?
Mert Akcakaya

48

IMHO c'est une question de goût personnel et de façons de penser. Je n'ai pas trop de problème avec OO.

Nous (ou du moins je) conceptualisons le monde en termes de relations entre les choses que nous rencontrons, mais l'objectif de la programmation orientée objet est de concevoir des classes individuelles et leurs hiérarchies.

IMHO ce n'est pas tout à fait, bien que cela puisse être une perception commune. Alan Kay, l'inventeur du terme OO, insistait toujours sur les messages envoyés entre les objets, plutôt que les objets eux - mêmes. Et les messages, du moins pour moi, dénotent des relations.

Notez que, dans la vie quotidienne, les relations et les actions existent principalement entre des objets qui auraient été des instances de classes non liées dans la POO.

S'il existe une relation entre les objets, ils sont liés, par définition. Dans OO, vous pouvez l'exprimer avec une dépendance d'association / agrégation / utilisation entre deux classes.

Nous pensons en termes de verbes bivalents (parfois trivalents, comme dans, par exemple, "je vous ai donné des fleurs") où le verbe est l'action (relation) qui agit sur deux objets pour produire un résultat / une action. L'accent est mis sur l'action et les deux (ou trois) objets [grammaticaux] ont la même importance.

Mais ils ont toujours leurs rôles bien définis dans le contexte: sujet, objet, action, etc. "Je t'ai donné des fleurs" ou "Tu m'as donné des fleurs", ce n'est pas la même chose (sans parler de "Fleur que tu m'as donnée"): -)

Comparez cela à la POO où vous devez d’abord trouver un objet (nom) et lui dire d’exécuter une action sur un autre objet. La façon de penser passe des actions / verbes opérant sur les noms à des noms opérant sur des noms - c'est comme si tout était dit à la voix passive ou réfléchie, par exemple, "le texte est affiché par la fenêtre du terminal". Ou peut-être "le texte se dessine sur la fenêtre du terminal".

Je ne suis pas d'accord avec ça. IMHO la phrase anglaise "Bill, go to hell" se lit plus naturellement dans le code du programme bill.moveTo(hell)plutôt que move(bill, hell). Et le premier est en fait plus analogue à la voix active d'origine.

Ainsi, il faut décider si on va dire terminalWindow.show (someText) ou someText.show (terminalWindow)

Encore une fois, ce n’est pas la même chose de demander au terminal d’afficher du texte ou de demander au texte d’afficher le terminal. À mon humble avis, celui qui est le plus naturel est assez évident.

Compte tenu de ces problèmes, comment et pourquoi est-il arrivé que la manière traditionnelle de faire de la programmation orientée objet soit devenue si populaire?

Peut-être parce que la majorité des développeurs OO voient OO différemment de vous?


15
+1 pour mentionner directement ces messages entre objets et leur importance d'Alan Kay
bunglestink

3
@zvrba, en effet, il y avait aussi d'autres pionniers de l'OO, mais c'est à côté du sujet de la discussion. "Le plus naturel est de demander que le texte soit affiché." - Maintenant, vous utilisez la même voix passive que vous avez déclarée comme étant "non naturelle" en POO.
Péter Török

5
@zvrba, vous dites qu'il y a toujours un "agent" [...] faisant quelque chose, tout en protestant contre l'approche OO consistant à identifier et nommer ces agents (objets) et à les traiter comme des citoyens de premier ordre dans la langue . Pour moi, cela fait partie de la modélisation du domaine problématique - vous devez quand même effectuer ce travail. Il suffit ensuite de mapper le modèle de domaine résultant en code d'une manière différente, selon que votre langage est OO ou non.
Péter Török

6
@zvrba, ce n'est pas OO en tant que tel, mais un développeur / concepteur qui décide des rôles et des responsabilités des différents objets. L'utilisation de l'approche OO peut générer des modèles ou des conceptions de domaine, bonnes ou mauvaises, tout comme l'utilisation d'un couteau peut vous procurer une fine tranche de pain ou un doigt qui saigne. Néanmoins, nous ne blâmons pas le couteau, car il ne s'agit que d'un outil. Notez également que les concepts / objets / agents du modèle sont des abstractions de choses dans le monde réel et, en tant que tels, sont toujours limités et déformés, en se concentrant uniquement sur des aspects spécifiques "intéressants".
Péter Török

6
@zvrba, une voiture ne démarre effectivement pas, comme le Carferait un objet start()uniquement lorsque sa méthode est explicitement appelée par quelqu'un.
Péter Török

10

Certains programmeurs ont du mal à utiliser OOD car ils aiment réfléchir à la façon de résoudre le problème pour l'ordinateur, et non à la résolution du problème.

... mais l'objectif de la programmation orientée objet est de concevoir des classes individuelles et leurs hiérarchies.

OOD n'est pas à ce sujet. OOD consiste à déterminer comment les choses se comportent et interagissent.

Nous pensons en termes de verbes bivalents (parfois trivalents, comme dans, par exemple, "je vous ai donné des fleurs") où le verbe est l'action (relation) qui agit sur deux objets pour produire un résultat / une action. L'accent est mis sur l'action et les deux (ou trois) objets [grammaticaux] ont la même importance.

L'accent mis sur OOD est toujours sur l'action, où les actions sont les comportements des objets. Les objets ne sont rien sans leurs comportements. La seule contrainte d'objet de OOD est que tout doit être fait par quelque chose.

Je ne pense pas que l'auteur soit plus important que le fait d'avoir fait quelque chose.

Mais pourquoi encombrer les gens de décisions aussi triviales sans conséquences opérationnelles alors qu’on entend vraiment montrer (terminalWindow, someText)?

Pour moi, c'est la même chose avec une notation différente. Vous devez encore décider qui est le show-er et qui est le show-ee. Une fois que vous savez cela, il n'y a pas de décision dans OOD. Windows afficher le texte -> Window.Show (texte).

Beaucoup de choses (surtout dans le domaine des legs) disent que c'est OO quand ça ne l'est pas. Par exemple, il existe une énorme quantité de code C ++ qui ne met pas en œuvre une figure de OOD.

OOD est facile une fois que vous sortez de l'état d'esprit que vous résolvez un problème pour les ordinateurs. Vous résolvez des problèmes pour des choses qui font des choses.


10
Je n'aime pas OOD exactement parce que je préfère réfléchir à la façon de résoudre le problème, point final. Je ne veux pas penser à la façon de traduire le langage naturel d'un domaine problématique dans un monde étranger d'objets, de messages, d'héritage, etc. Je ne veux pas inventer des taxonomies hiérarchiques où elles n'existent pas naturellement. Je veux décrire le problème dans son langage naturel et le résoudre le plus simplement possible. Et, d'ailleurs, le monde n'est pas fait que de "choses qui font des trucs". Votre vision de la réalité est extrêmement étroite.
SK-logic

7
@ Matt Ellen, j'écris des programmes qui modélisent le comportement d'entités qui ne sont pas des "choses" et qui ne "font" pas de "choses". Toute entité immuable ne fait rien. Toute fonction mathématique pure ne fait rien - ce n'est qu'un mappage d'un ensemble à un autre, et ce monde est principalement décrit par de telles fonctions. Tout formalisme logique ne "fait" rien. Oui, OOD ne m'aidera pas, car je peux utiliser des modèles et des abstractions beaucoup plus puissants. Revenir à un OOD primitif, limité, limitant me handicapera gravement.
SK-logic

2
@ Matt Ellen, oui, j'aimerais voir des références qui soutiennent de telles affirmations étranges que le monde est mieux perçu comme une collection de "choses qui font des choses" ou "d'objets qui interagissent via des messages". C'est complètement contre nature. Prenez n'importe quelle théorie scientifique (car elles sont toutes aussi proches de la modélisation du monde réel que possible à ce stade) et essayez de la réécrire en utilisant votre terminologie. Le résultat sera maladroit et délicat.
SK-logic

4
@ Antonio2011a, il n'existe pas de paradigme unique de programmation ou de modélisation capable de couvrir efficacement tous les domaines problématiques possibles. POO, fonctionnel, flux de données, logique de premier ordre, etc. - ce sont tous des paradigmes spécifiques à un domaine de problème et rien de plus. Je ne fais que prôner la diversité et l'ouverture d'esprit face à la résolution de problèmes. Réduire votre pensée à un seul paradigme est simplement stupide. La chose la plus proche d'une approche universelle, sans vous limiter à un seul cadre sémantique, est en.wikipedia.org/wiki/Language-oriented_programming
SK-logic le

3
@Calmarius pourquoi voudriez-vous rendre la programmation plus facile pour les ordinateurs? C'est juste idiot. Ce sont les humains qui doivent faire le travail le plus dur.
Matt Ellen

7

Peut-être que je ne peux pas comprendre le point, mais:

En lisant le premier livre sur la POO (début des années 90, le manuel élancé de Borland à Pascal), j'ai été simplement surpris par sa simplicité et son potentiel. (Avant, j'utilisais le cobol, le fortran, le langage d'assemblage et d'autres éléments préhistoriques.)

Pour moi, c'est assez clair: un chien est un animal, un animal doit manger, mon chien est un chien, il doit donc manger ...

De l'autre côté, la programmation elle-même est intrinsèquement artificielle (c'est-à-dire artificielle). Le langage humain est artificiel (ne me blâmez pas, nous avons tous appris notre langue auprès des autres, personne ne connaît la personne qui a inventé l'anglais). Selon certains scientifiques, l'esprit de l'homme est formé par le langage qu'il a appris en premier.

J'admets que certaines constructions dans les langages OO modernes sont un peu gênantes, mais c'est l'évolution.


1
Quelle était exactement votre tâche pour vous de passer de cobol à fortran, puis de montage (et du reste)?
Rook

1
Mauvais ordre. En fait, j'ai commencé avec Basic, puis je suis passé à Fortran, puis à Assembly et à Cobol (oui, c'est le bon ordre: Assembly en premier). Le premier ordinateur de ma vie était un ordinateur "gigantesque", 256 Ko de mémoire, une machine à écrire et sa console, alimentée avec des cartes perforées, car j'étais son opérateur. Quand je me suis levé assez pour devenir programmeur système, un objet suspect appelé PC-AT a atterri à mon bureau. Je me suis donc plongé dans GW-Basic, Turbo-Pascal,… et ainsi de suite.
Nerevar

1
Je ne parlais pas de ça. Plus à votre domaine d'emploi; Parce que je ne connais pas beaucoup de gens (qui que ce soit vraiment) qui traitaient avec COBOL (orienté business), fortran (domaine scientifique), assembleur (plus orienté cs) et ensuite ces autres. Néanmoins, qu'ils soient programmeurs professionnels ou non.
Rook

1
Pas de mystère: rejoindre des équipes et des projets pour lesquels une décision en matière de laguage avait déjà été prise. Et un niveau de curiosité non négligeable concernant les outils qu'ils utilisaient.
Nerevar

6

Une des choses qui m'a rendu la tâche difficile, c'est de penser que la programmation orientée objet était une modélisation du monde. Je pensais que si je ne l'avais pas bien compris, quelque chose pourrait venir me mordre à la gorge (une chose est vraie ou ne l'est pas). J'étais très conscient des problèmes que prétendre que tout est un objet ou une entité. Cela m'a rendu très hésitant et peu confiant quant à la programmation en POO.

Ensuite, j'ai lu SICP et compris de nouveau qu'il était vraiment question de types de données et de contrôle de leur accès. Tous les problèmes que j’avais fondus parce qu’ils reposaient sur une fausse prémisse, à savoir que vous représentiez le monde sous OOP.

Je m'émerveille toujours de l'immense difficulté que cette fausse prémisse m'avait donnée (et de la façon dont je me suis laissé redevable).


Merci d'avoir signalé le danger d'essayer de modeler le monde.
Sean McMillan

4

Oui, la programmation orientée objet elle-même est très peu naturelle - le monde réel n'est pas entièrement constitué de taxonomies hiérarchiques. Quelques petites parties de celle-ci sont constituées de ce matériau, et ces parties sont les seules choses qui pourraient être correctement exprimées en termes de OO. Tout le reste ne peut pas être naturellement inséré dans un mode de pensée aussi trivial et limité. Voir les sciences naturelles, voir combien de langages mathématiques différents ont été inventés pour exprimer de la manière la plus simple ou au moins compréhensible la complexité du monde réel. Et presque aucun d'entre eux ne peut être facilement traduit dans un langage d'objets et de messages.


5
Eh bien, cela est également vrai pour tout type de notation formelle essayant de décrire avec précision le monde réel.
Péter Török

1
@ Péter Török, précisément ce que je veux dire. Il n'y a pas de formalisme unique qui couvre tout. Vous devez les utiliser tous, dans toute leur multitude effrayante. Et c’est la raison pour laquelle je crois en une programmation orientée langage - elle permet d’adopter divers formalismes, souvent incompatibles, en une entité de code solide.
SK-logic

1
Tout peut être catégorisé en taxonomies hiérarchiques. Le truc, c'est de trouver des solutions sensées. L'héritage multiple est souvent impliqué. Une grande différence entre les logiciels et le monde réel est que, dans le monde réel, nous devons souvent déduire ou découvrir les schémas de catégorisation; dans les logiciels, nous les inventons.
Caleb

1
En utilisant un terme comme "taxonomie hiérarchique", je pense que vous songez, eh bien, à l'héritage. Il est en effet difficile de raisonner l'héritage. C'est pourquoi les gens suggèrent d'utiliser la composition plutôt que l'héritage.
Frank Shearar

1
@Frank: Il existe de nombreux types de taxonomies hiérarchiques dans le monde réel, dont l'héritage n'est qu'un. Faire ceci correctement nécessite de meilleurs outils que la POO (par exemple, le raisonnement ontologique) et pose des problèmes aux philosophes depuis des millénaires…
Donal Fellows

4

Nous (ou du moins je) conceptualisons le monde en termes de relations entre les choses que nous rencontrons, mais l'objectif de la programmation orientée objet est de concevoir des classes individuelles et leurs hiérarchies.

Vous partez de (IMO) d'une fausse prémisse. Les relations entre les objets sont sans doute plus importantes que les objets eux-mêmes. Ce sont les relations qui donnent une structure de programme orientée objet. L'héritage, la relation entre les classes, est bien sûr important car la classe d'un objet détermine ce que cet objet peut faire. Mais ce sont les relations entre les objets individuels qui déterminent ce que fait réellement un objet dans les limites définies par la classe, et donc le comportement du programme.

Le paradigme orienté objet peut être difficile au début, non pas parce qu'il est difficile d'imaginer de nouvelles catégories d'objets, mais parce qu'il est difficile d'envisager un graphe d'objets et de comprendre quelles devraient être les relations entre eux, en particulier lorsque vous ne possédez pas un objet. façon de décrire ces relations. C'est pourquoi les modèles de conception sont si utiles. Les modèles de conception concernent presque entièrement les relations entre les objets. Les modèles nous fournissent à la fois les éléments de base que nous pouvons utiliser pour concevoir les relations d’objet à un niveau supérieur et un langage que nous pouvons utiliser pour décrire ces relations.

La même chose est vraie dans les domaines créatifs qui fonctionnent dans le monde physique. N'importe qui peut créer un groupe de pièces et appeler cela un bâtiment. Les chambres peuvent même être entièrement meublées avec tous les derniers accoutrements, mais cela ne fait pas le travail de la construction. Le travail d'un architecte consiste à optimiser les relations entre ces salles en fonction des besoins des personnes utilisant ces salles et de l'environnement du bâtiment. La réussite de ces relations est ce qui fait qu'un bâtiment fonctionne à la fois d'un point de vue fonctionnel et esthétique.

Si vous rencontrez des difficultés pour vous habituer à la programmation orientée objet, je vous encourage à réfléchir davantage à la manière dont vos objets s'intègrent et à l'organisation de leurs responsabilités. Si vous ne l'avez pas déjà fait, lisez à propos des modèles de conception - vous vous rendrez probablement compte que vous avez déjà vu les modèles qui vous intéressent, mais leur donner des noms vous permettra de voir non seulement des arbres, mais aussi des peuplements, des bosquets, des bosquets, les bois, les bosquets, les boisés et éventuellement les forêts.


3

Ceci est seulement une partie de ce qui ne va pas avec la POO.

Essentiellement, les fonctions deviennent des citoyens de seconde classe, ce qui est mauvais.

Les langages modernes (ruby / python) ne souffrent pas de ce problème et fournissent des fonctions en tant qu'objets de première classe, tout en vous permettant de créer des programmes sans créer de hiérarchie de classes.


La POO me semble très naturelle, il m'est en fait difficile de penser à programmer des tâches autrement. Pourtant, au fil des ans, j'ai fini par comprendre que la POO avait tendance à accorder trop d'importance aux noms aux verbes. Ce coup de gueule de 2006 m'a aidé à comprendre cette distinction: steve-yegge.blogspot.com/2006/03/…
Jim In Texas

3

OOP n'est pas difficile. Ce qui le rend difficile à utiliser, c’est une compréhension superficielle de son utilité, dans laquelle les programmeurs entendent des maximes au hasard et se les répètent à voix basse pour recevoir les bénédictions du divin Gang of Four, du bienheureux Martin Fowler, ou quiconque d'autre qu'ils ont lu.


3

ÉDITÉ

Tout d’abord, je voudrais dire que je n’ai jamais trouvé la POO difficile, ni plus difficile que d’autres paradigmes de programmation. La programmation est intrinsèquement difficile car elle tente de résoudre des problèmes du monde réel et le monde réel est extrêmement complexe. Par contre, en lisant cette question, je me suis posé la question suivante: la POO est-elle "plus naturelle" que d’autres paradigmes? Et donc plus efficace?

Une fois, j’ai trouvé un article (j’aimerais souhaiter le retrouver afin de pouvoir le poster à titre de référence) sur une étude comparative entre la programmation impérative (IP) et la programmation orientée objet (OOP). Ils avaient essentiellement mesuré la productivité des programmeurs professionnels utilisant IP et OOP dans différents projets, et le résultat était qu'ils n'avaient pas constaté de grandes différences. Ainsi, l’affirmation était qu’il n’y avait pas de grande différence de productivité entre les deux groupes et que ce qui comptait vraiment, c’était l’expérience.

D’autre part, les partisans de l’orientation par objets affirment que, même si, au début du développement d’un système, la POO peut même prendre plus de temps qu’impératif, le code est plus facile à maintenir et à étendre du fait de l’intégration étroite des données entre les utilisateurs. opérations.

J'ai principalement travaillé avec des langages POO (C ++, Java), mais j'ai souvent le sentiment que je pourrais être aussi productif avec Pascal ou Ada, même si je ne les ai jamais essayés pour de grands projets.

Comparez cela à la POO où vous devez d’abord trouver un objet (nom) et lui dire d’exécuter une action sur un autre objet.

[Couper]

Je dirais donc que la façon habituelle de faire de la programmation orientée objet (classe unique, envoi unique) est difficile car elle n’EST PAS NATURELLE et ne correspond pas à la façon dont les humains perçoivent le monde. Les méthodes génériques de CLOS sont plus proches de ma façon de penser, mais hélas, cette approche n’est pas généralisée.

Lorsque j'ai lu ce dernier paragraphe plus attentivement, j'ai enfin compris le point essentiel de votre question et j'ai dû réécrire ma réponse à partir de zéro. :-)

Je connais d’autres propositions d’OA dans lesquelles plusieurs objets reçoivent un message au lieu d’un seul, c’est-à-dire que plusieurs objets jouent un rôle symétrique lors de la réception d’un message. OUI, cela me semble une approche plus générale et peut-être plus naturelle (moins restrictive).

D'autre part, "l'envoi multiple" peut être facilement simulé en utilisant "l'envoi unique" et "l'envoi unique" est plus facile à mettre en œuvre. C’est peut-être une des raisons pour lesquelles la "répartition multiple" n’est pas devenue une pratique courante.


3

Arrêtez de rechercher un paradigme exclusivement POO et essayez du JavaScript.

Je suis actuellement en train de définir un schéma dans lequel mes objets d'interface utilisateur fonctionnent dans une interface pilotée par les événements. C'est-à-dire que j'aurai ce qui ressemble à une méthode publique typique qui, lorsqu'elle est renvoyée, donne lieu à une action définie en interne. Mais quand il est déclenché, ce qui se passe réellement, c'est que je déclenche un événement sur l'objet lui-même et qu'un gestionnaire prédéfini à l'intérieur de cet objet répond. Cet événement et l'objet d'événement auquel vous pouvez associer des propriétés qui sont transmises à tout autre auditeur peuvent être entendus par tout ce qui est attentif à l'écoute. Vous pouvez écouter directement l'objet, ou vous pouvez généralement écouter ce type d'événement (les événements sont également déclenchés sur un objet générique que tous les objets construits par la fabrique peuvent écouter). Ainsi, par exemple, j'ai une liste déroulante dans laquelle vous sélectionnez un nouvel élément dans la liste déroulante.

Si vous le souhaitez (et j'ai été surpris de découvrir que ce n'est généralement pas le cas - c'est un problème de lisibilité lorsque vous ne pouvez pas voir d'où provient l'événement), vous pouvez effectuer un découplage complet de l'objet et établir un contexte via un objet événement transmis. Quoi qu'il en soit, vous évitez toujours les envois uniques en pouvant enregistrer plusieurs intervenants.

Mais je ne fais pas cela avec OOP uniquement et JS n’est même pas «correctement» OOP selon certaines définitions, ce que je trouve hilarant. À mon avis, le niveau de développement d’applications supérieur est correct, c’est le pouvoir de modifier le paradigme en fonction de ce qui convient à votre situation et nous pouvons imiter les classes à la perfection si nous le souhaitons. Mais dans ce cas, je mélange des aspects fonctionnels (transfert des gestionnaires) avec la POO.

Plus important encore, ce que j'ai se sent assez puissant. Je ne pense pas en termes d'objet agissant sur un autre. En gros, je décide de ce qui importe aux objets, en leur donnant les outils dont ils ont besoin pour régler les problèmes, en les glissant simplement dans un mélangeur et en les laissant réagir les uns par rapport aux autres.

Je suppose donc que ce que je dis est le suivant: ce n’est pas un problème de déclaration de substitution. C'est mélanger et assortir. Le problème, ce sont les langages et les modes qui veulent que vous croyiez que c’est une chose qui est trop chère. Comment un développeur java junior, par exemple, peut-il vraiment apprécier la programmation orientée objet alors qu’il pense qu’il le fait toujours correctement par défaut?


2

On m'a expliqué que c'était avec un grille-pain et une voiture. Les deux ont des ressorts, donc vous auriez un objet "ressort" et ils seraient de tailles, de forces différentes et peu importe, mais ils seraient tous deux des "ressorts" et étendreaient ensuite cette métaphore sur la voiture, si vous aviez beaucoup de roues (Roues, évidemment, plus le volant, etc.) et cela avait beaucoup de sens.

Vous pouvez alors voir le programme comme une liste d'objets, et il est beaucoup plus simple de visualiser "C'est une liste de choses qui font des choses, donc ce n'est pas comme cette liste d'instructions que vous avez vues auparavant"

Je pense que le vrai problème avec la POO est la façon dont cela est expliqué aux gens. Souvent (dans mes cours d'université), je vois cela s'expliquer en disant "il s'agit de beaucoup de classes qui font de petites choses, et vous pouvez créer des objets à partir de cela" et cela déroute beaucoup de gens, parce qu'il utilise ce qui est essentiellement abstrait termes pour expliquer ces concepts, plutôt que des idées concrètes que les gens ont saisies quand ils avaient 5 ans et qui jouaient avec le lego.


2
Les sources se présentent sous des millions de formes, qui remplissent toutes des fonctions similaires . Je dirais que ceci est un exemple parfait pour la programmation fonctionnelle.
l0b0

2

C'est la façon naturelle de penser le monde à travers la catégorisation. C'est plus ou moins ce que OO est à propos. La POO est difficile parce que la programmation est difficile.


Mais est-ce que vous catégorisez selon que certains objets ont des attributs communs ou des comportements communs? Est-ce que tout ce qui a un nom et un prénom est une personne? Est-ce que tout ce qui marche est un animal?
Zvrba

En ce qui concerne la catégorisation, la capacité à exécuter un certain comportement est un attribut. Les zèbres et les chevaux peuvent se reproduire, mais la progéniture est un hybride. Il est très difficile de prédire ce résultat en fonction de la fonction d’accouplement, à moins que vous sachiez qu’elles ne sont pas de la même espèce.
JeffO

1
@zvrba: Ma réponse à la question posée dans le commentaire est la suivante it doesn't matter. Tout ce qui a un nom et un nom de famille est une personne pour chaque programme qui ne se soucie que des gens. Pour tout programme qui n'a aucune connaissance des personnes ou des non-personnes, c'est un IHasNameAndSurname. Les objets doivent seulement résoudre le problème à résoudre.
Tom W

@Jeff O Même au sein d'une même espèce / race / population, il existe des variations et aucun exemple idéal (essentiel). Donc, oui, OO n'est pas comme la nature, mais c'est un bon ajustement à la façon dont les humains pensent naturellement.
Tom Hawtin - tackline

2

Je pense qu'une partie de la difficulté survient lorsque les gens essaient d'utiliser la POO pour représenter la réalité. Tout le monde sait qu'une voiture a quatre roues et un moteur. Tout le monde sait que les voitures peuvent Start(), Move()et SoundHorn().

Une lumière claqua dans ma tête lorsque je compris que je devais arrêter d'essayer de le faire tout le temps. Un objet n'est pas la chose avec laquelle il partage un nom. Un objet est (doit être) une partition de données suffisamment détaillée et pertinente pour l’ampleur du problème. C’est oughtexactement ce dont la solution au problème a besoin, ni plus ni moins. Si rendre un objet responsable d'un comportement entraîne plus de lignes de code que le même comportement étant le travail d'un tiers nébuleux (certains pourraient l'appeler un «poltergeist»), alors le poltergeist gagne ses jetons.


1

Afin de gérer la complexité, nous devons regrouper les fonctionnalités dans des modules, ce qui est un problème difficile en général. C'est comme le vieil adage du capitalisme, OOP est le pire système pour organiser des logiciels, à l'exception de tout ce que nous avons essayé.

La raison pour laquelle nous groupons les interactions au sein des noms, même s’il existe souvent une ambiguïté quant au nom du groupe avec lequel le grouper, est due au fait que la quantité de noms se trouve dans des classes de taille gérable, alors que le regroupement par verbes a tendance à produire de très petits groupes comme des ponctuels ou de très grands groupes pour une fonction comme un spectacle . Les concepts de réutilisation tels que l'héritage s'avèrent également beaucoup plus faciles lors du regroupement par noms.

De plus, la question de décider de mettre en évidence la fenêtre ou le texte est presque toujours beaucoup plus claire en pratique qu'en théorie. Par exemple, presque tous les groupes de kits d’outils graphiques s’ajoutent au conteneur mais s’affichent avec le widget. Si vous essayez d'écrire du code dans l'autre sens, la raison apparaît assez rapidement, même si vous y réfléchissez de manière abstraite, les deux méthodes semblent interchangeables.


2
Avez-vous déjà vu un système de module approprié ? Comment pouvez-vous dire que la POO est la meilleure chose disponible? Les modules SML sont beaucoup, beaucoup plus puissants. Cependant, même les forfaits Ada suffisent dans la plupart des cas, même sans un soupçon minime de POO.
SK-logic

@ SK-logic, je pense que vous vous attachez à des définitions trop précises. Par OOP, je ne veux pas dire de classes , je veux dire logiquement regrouper les "verbes" en fonction des "noms" sur lesquels ils opèrent, et pouvoir réutiliser et spécialiser ces verbes en fonction des noms particuliers sur lesquels ils sont utilisés. Les classes sont l’implémentation la plus connue, mais ne sont pas les seules . Je reconnais que je ne connaissais pas les modules SML, mais le premier exemple que j’ai vu lorsque j’y ai jeté un coup d’œil était une implémentation d’une file d’attente pouvant provenir de tout livre de conception d’OO avec des modifications de syntaxe pour la rendre fonctionnelle.
Karl Bielefeldt

il ne serait tout simplement pas juste d'accorder à un malheureux OOP trop de crédit pour quelque chose qui ne lui appartient pas. Les modules sont une excellente invention. Les modules de première classe sont fantastiques. Mais la POO n'a rien à voir avec eux. Certains langages POO ont adopté certaines fonctionnalités du module (notamment les espaces de noms), mais les modules sont un concept beaucoup plus général et puissant que les classes. Vous avez dit que les cours sont "les meilleurs", ce qui est loin de la vérité. Les modules de première classe sont bien meilleurs. Et, bien sûr, les systèmes de types sont beaucoup plus larges et profonds qu’un simple objet d’exploitation avec son sous-typage.
SK-logic

1
"C'est comme le vieil adage du capitalisme, la POO est le pire système pour organiser des logiciels, à l'exception de tout ce que nous avons essayé.": Peut-être que nous n'avons pas essayé assez longtemps. :-)
Giorgio

1
Je pense que vous voulez dire «démocratie»: quotationspage.com/quote/364.html
nicodemus13

1

Non . Il existe plusieurs façons de résoudre un problème à l'aide de la programmation: fonctionnelle, procédurale, logique, POO, autre.

Dans le monde réel, les gens utilisent parfois le paradigme fonctionnel, parfois le paradigme procédural, etc. Et parfois nous nous sommes mélangés. Et finalement, nous les représentons comme un style ou un paradigme particulier de programmation.

Il existe également le paradigme "tout est une liste ou un élément", utilisé dans LISP. J'aime parler d'une chose différente de la programmation fonctionnelle . PHP utilise cela dans les tableaux associatifs.

Les paradigmes OOP et "Tout est une liste ou un élément" sont considérés comme deux des styles de programmation PLUS NATURELS , comme je me souviens dans certaines classes d'Intelligence Artificielle.

Cela me semble bizarre, "La POO n'est pas naturelle", peut-être que la façon dont vous apprenez, ou la façon dont vous avez été enseigné sur la POO est fausse, mais pas la POO elle-même.


1

Compte tenu de ces problèmes, comment et pourquoi est-il arrivé que la manière traditionnelle de faire de la programmation orientée objet soit devenue si populaire? Et que peut-on faire, le cas échéant, pour le détrôner?

OOP est devenu populaire car il offre des outils pour organiser votre programme à un niveau d'abstraction plus élevé que les langages procéduraux populaires qui l'ont précédé. Il était également relativement facile de créer un langage comportant une structure procédurale à l'intérieur des méthodes et une structure orientée objet les entourant. Cela a permis aux programmeurs qui savaient déjà comment programmer de manière procédurale de saisir les principes OO un à la fois. Cela a également conduit à beaucoup de programmes OO-in-name-only qui étaient des programmes procéduraux encapsulés dans une classe ou deux.

Pour détrôner OO, construisez un langage qui facilite la transition progressive de ce que la plupart des programmeurs savent aujourd'hui (essentiellement procédural, avec un peu d'OO) vers votre paradigme préféré. Assurez-vous qu'il fournit des API pratiques pour effectuer les tâches courantes et bien le promouvoir. Les gens vont bientôt créer des programmes X-in-name-only dans votre langue. Ensuite, vous pouvez vous attendre à ce que cela prenne des années et des années pour que les gens s’exercent réellement à la pratique de X.


Le PO ne soutient pas que OO est mauvais en général et devrait être détrôné, mais que la "manière traditionnelle de faire de la PO" actuellement n'est pas la plus naturelle (comparée à la "dépêche multiple").
Giorgio

OP semble également trop axé sur la définition de la hiérarchie des types, où les meilleurs programmes d’OA ont tendance à s’appuyer davantage sur les interfaces et la composition. Si la répartition multiple correspond à X, créer un langage permettant aux utilisateurs d’apprendre progressivement les compétences associées à la répartition multiple reste la solution pour changer l’environnement.
Sean McMillan

1

Je pense que les langues OOP et OOP ont aussi des problèmes.

Si vous le comprenez bien, la POO concerne les boîtes noires (objets) sur lesquelles se trouvent des boutons qui peuvent être enfoncés (méthodes). Les classes ne sont là que pour aider à organiser ces boîtes noires.

L'un des problèmes est que le programmeur place les boutons sur le mauvais objet. Le terminal ne peut pas afficher le texte sur lui-même, le texte ne peut pas s'afficher sur le terminal. Le composant du gestionnaire de fenêtres du système d'exploitation qui peut le faire. La fenêtre de terminal et le texte sont juste une entité passive. Mais si nous pensons ainsi, nous réalisons que la plupart des entités sont des choses passives et que nous n’aurions que très peu d’objets capables de faire quoi que ce soit (ou tout simplement un: l’ordinateur ). En effet, lorsque vous utilisez C, vous l’organisez en modules, ceux-ci ne représentent que quelques objets.

Un autre point est que l'ordinateur exécute simplement les instructions de manière séquentielle. Supposons que vous avez un VCRet un Televisionobjet, comment joueriez-vous la vidéo? Vous écrivez probablement quelque chose comme ceci:

connect(television, vcr);
vcr.turnOn();
television.turnOn();
insert(vcr, yourFavoriteCasette);
vcr.play();
while (vcr.isPlaying()) {} // Wait while the VCR is playing the casette.
vcr.eject();
vcr.turnOff();
television.turnOff();

Ce serait aussi simple que cela, mais il vous faudrait au moins 3 processeurs ( ou processus ) pour cela: l'un joue votre rôle, le second est le magnétoscope, le troisième est le téléviseur. Mais normalement, vous n’avez qu’un seul noyau (du moins pas assez pour tous vos objets). À l'université, bon nombre de mes camarades ne comprenaient pas pourquoi l'interface graphique se fige lorsqu'un bouton-poussoir effectue une opération coûteuse.

Donc, je pense qu'un design orienté objet peut très bien décrire le monde, mais ce n'est pas la meilleure abstraction pour ordinateur.


0

Jetez un coup d'œil à la DCI (données, contexte et interaction) inventée par l'inventeur du modèle MVC.

Le but de DCI est (cité dans Wikipedia):

  • Donne au comportement du système un statut de première classe, au-dessus des objets (noms).
  • Séparer proprement le code pour que le comportement du système change rapidement (ce que fait le système) du code pour modifier lentement la connaissance du domaine (ce qu'est le système), au lieu de combiner les deux dans une interface de classe.
  • Soutenir un style de pensée objet qui est proche des modèles mentaux des gens, plutôt que le style de pensée de classe.

Voici un bon article écrit par les auteurs et voici un petit exemple d'implémentation (.NET) si vous voulez voir du code. C'est beaucoup plus simple que cela puisse paraître et cela semble très naturel.


0

On entend souvent que la POO correspond naturellement à la façon dont les gens perçoivent le monde. Mais je suis fortement en désaccord avec cette affirmation (...)

Comme il est évangélisé dans les livres et ailleurs pendant des décennies, je ne suis pas d'accord avec cela aussi. Néanmoins, je pense que ce sont Nygaard et Dahl qui ont formulé cette idée, et ils se sont concentrés sur le fait qu'il était plus facile de concevoir des simulations par rapport aux solutions de rechange de l'époque.

(...) mais l'objectif de la programmation orientée objet est de concevoir des classes individuelles et leurs hiérarchies.

Cette affirmation entre dans un territoire sensible compte tenu de la popularité répandue des idées fausses sur la programmation orientée objet et de la sensibilité à la définition de OO J'ai plus de dix ans dans le domaine, travaillant à la fois dans l'industrie et dans la recherche universitaire sur les prog. langues, et je peux vous dire que j'ai passé de nombreuses années à désapprendre le "grand public", car j'ai commencé à remarquer à quel point il était différent (et inférieur) de ce que les premiers créateurs visaient. Pour un traitement moderne et actualisé du sujet, je me référerai aux récents efforts de W. Cook:

"Proposition de définitions modernes et simplifiées des termes" objet "et" objet ", http://wcook.blogspot.com.br/2012/07/proposal-for-simplified-modern.html

Compte tenu de ces problèmes, comment et pourquoi est-il arrivé que la manière traditionnelle de faire de la programmation orientée objet soit devenue si populaire?

Peut-être la même raison pour laquelle les claviers QWERTY sont devenus populaires ou la même raison pour laquelle le système d'exploitation DOS est devenu populaire. Les choses se passent simplement avec des véhicules populaires, malgré leurs propriétés, et deviennent populaires eux-mêmes. Et parfois, des versions similaires mais pires de quelque chose sont considérées comme la chose réelle.

Et que peut-on faire, le cas échéant, pour le détrôner?

Ecrivez un programme en utilisant une approche supérieure. Écrivez le même programme en utilisant une approche orientée objet. Montrer que le premier a de meilleures propriétés que le dernier dans tous les aspects significatifs (propriétés du système lui-même et propriétés techniques). Montrez que le programme choisi est pertinent et que l'approche proposée préserve la haute qualité des propriétés si elle est appliquée à d'autres types de programmes. Soyez rigoureux dans votre analyse et utilisez des définitions précises et acceptées lorsque cela est nécessaire.

Enfin, partagez vos découvertes avec nous.


-1

Prenons Java: les objets sont une sorte de goulet d’étranglement d’abstraction. La plupart des «choses» sont soit strictement des sous-composants d’objets, soit utilisent des objets comme sous-composants. Les objets doivent être suffisamment polyvalents pour constituer une couche d'abstraction complète entre ces deux types de choses - cela signifie qu'il n'y a pas de métaphore unique dans laquelle ils incarnent. En particulier, Java fait des objets (& classes) la seule couche par laquelle vous appelez / envoyez le code. Cette quantité de choses que les objets incarnent les rend franchement beaucoup trop complexes. Toute description utile de celles-ci doit être limitée à une forme spécialisée ou restreinte.

Les hiérarchies d'héritage et d'interface sont des "choses" qui utilisent des objets comme sous-composants. C'est une manière spécialisée de décrire des objets, pas une façon de tirer une compréhension générale des objets.

On peut dire que les "objets" ont ou ont beaucoup de choses, car ils constituent une abstraction à usages multiples plus ou moins universelle dans un "langage à l'origine". S'ils sont utilisés pour contenir un état mutable local ou pour accéder à un état mondial externe, ils ressemblent beaucoup à un "nom".

En revanche, un objet qui représente un processus, par exemple "chiffrer", "compresser" ou "trier", ressemble à un "verbe".

Certains objets sont utilisés pour leur rôle d'espaces de noms, par exemple un emplacement pour placer une fonction "statique" en Java.

Je suis enclin à souscrire à l'argument selon lequel Java est trop lourd en appels de méthodes d'objet, avec une répartition sur l'objet. C'est probablement parce que je préfère les classes de types de Haskell pour contrôler la répartition. Ceci est une limitation de la distribution et est une fonctionnalité de Java mais pas la plupart des langues, ni même la plupart des langages OO.


-3

J'ai assisté et participé à de nombreux débats en ligne sur la POO. Les partisans de la programmation orientée objet ne savent généralement pas comment écrire le code de procédure approprié. Il est possible d’écrire un code de procédure hautement modulaire. Il est possible de séparer le code et les données et de s'assurer que les fonctions ne peuvent écrire que dans leur propre magasin de données. Il est possible de mettre en œuvre le concept d'héritage à l'aide d'un code de procédure. Plus important encore, le code de procédure est plus fin, plus rapide et plus facile à déboguer.

Si vous construisez des modules à fichier unique avec des conventions de dénomination strictes, le code de procédure est plus facile à écrire et à gérer que OO et il en fera de même ou plus et plus rapidement. Et n'oubliez pas que lorsque votre application est exécutée, elle est toujours procédurale, quel que soit le nombre de classes présentes dans votre script.

Vous avez ensuite le problème des langages tels que PHP, qui ne sont pas vraiment orientés objet et reposent sur des hacks pour simuler des éléments tels que l’héritage multiple. Les gros lanceurs qui influencent la direction du langage ont transformé PHP en un patchwork de règles incohérentes devenues trop volumineuses pour l’objectif initial. Quand je vois des développeurs écrire d’énormes classes de templates pour ce qui était conçu comme un langage de template procédural, je ne peux pas m'empêcher de sourire.

Si vous comparez un code OO correctement écrit avec un code procédural mal écrit, vous aboutirez toujours à une conclusion erronée. Très peu de projets justifient une conception orientée objet. Si vous êtes IBM et gérez un énorme projet qui doit être maintenu pendant des années par plusieurs développeurs, optez pour Object Oriented. Si vous écrivez un petit blog ou un site Web de shopping pour un client, réfléchissez-y à deux fois.

Pour répondre à la question initiale, la programmation orientée objet est difficile car elle ne résout pas les dilemmes de la programmation dans la vie réelle sans recourir à des solutions 100 fois plus complexes qu'elles ne devraient l'être. L'utilisation judicieuse de données globales est l'une des solutions les plus puissantes à de nombreux problèmes de programmation. Pourtant, les diplômés universitaires de la nouvelle vague vous diront que c'est un gros non-non. Les données disponibles dans le monde entier sont dangereuses uniquement si vous êtes un lapin de programmation maladroit. Si vous avez mis en place un ensemble de règles strictes et des conventions de dénomination appropriées, vous pouvez vous passer de la globalisation de toutes vos données.

Il devrait être obligatoire pour tout programmeur orienté objet de savoir écrire une application de jeu d'échecs en assembleur pour une mémoire disponible maximale de 16K. Ils apprendraient ensuite à couper la graisse, à réduire la paresse et à trouver des solutions ingénieuses.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.