Le concept de l'orienté objet

a marqué ce sujet comme résolu.

C'est un peu à cause de moi si ce sujet existe, donc il me faut bien y répondre  :-°

Je trouve dommage que l'historique soit aussi bref. Même s'il n'y a pas nécessairement grand-chose à dire, je serais curieux de savoir quelle a été la réflexion des deux Norvégiens (dont je ne mettrais même pas le nom entre parenthèses, ils sont tout de même à l'origine de ce qui est présenté ;) ) : ce qui les gênait dans leur façon de programmer, ce qu'ils ont eu comme premières idées, bref, le cheminement du procédural à l'objet — s'il y a moyen de trouver ces informations, évidemment.

Pour l'extrait de présentation "La POO", je trouve que les réponses aux questions sont très brèves, elles aussi. "La POO est une manière de programmer." J'ai bien peur que le lecteur le sache déjà… Ce qu'il aimerait savoir (et il "pose la question", d'ailleurs), c'est en quoi elle se démarque des autres. Les questions qui vont servir de fil rouge pour l'extrait sont toutes posées ensembles, pourquoi ne pas y répondre sans ajouter de titres ? L'enchaînement et l'explication permettraient d'être moins abrupte qu'avec ces titres, qui coupent parfois en très petits bouts l'extrait, à mon avis.
Aussi, j'éviterais de parler des "langages les plus communs", "les plus connus", etc.. Dites plutôt que "parmi les langages qui utilisent l'orienté objet, on peut trouver…", qui est plus neutre, et qui donne donc moins l'impression de discriminer ni d'autres langages qui pourraient être dans la liste, ni ceux qui ne permettent pas l'orienté objet.

Si vous posez des questions, comme après votre exemple en JAVA, mettez-en toutes les réponses, sans quoi les lecteurs peuvent ne pas comprendre où vous voulez en venir. La dernière question, notamment : mettez quelque chose comme « On a trois fois plus de lignes de code en procédural qu'en orienté objet !1 »
Notez que certains pourraient aussi croire que vous vous fichez d'eux s'ils n'arrivent pas à voir ce que vous voulez leur faire voir…

Pour la partie "Les objets", je ne citerais pas PHP comme l'un de ceux qui utilisent le destructeur. L'utilisation de celui-ci dans ce langage me paraît être bien moins importante qu'en C++, par exemple.
Aussi, si vous comparez les objets IRL et les objets en programmation, mettez les deux exemples. Vous parlez de la voiture avec ses attributs et ses fonctions, parlez donc de la classe voiture avec ses propriétés et ses méthodes, cela vous permet de mieux parler de ces dernières et de créer le parallèle directement. Un lecteur pourra ainsi mieux se représenter la chose qu'en tombant sur le mot méthode (mis en gras plus loin, donc c'est important) au milieu du texte.
En parlant de gras, n'hésitez pas non-plus à l'utiliser la première fois que vous utilisez un terme important, pour autant que ce terme soit expliqué. Utilisez l'italique si vous avez des notions importantes qui sont reprises dans l'explication d'un nouveau terme important.

Génial ! Mais on à quoi ça sert, au juste?

Euh, non, c'est très utile !

http://zestedesavoir.com/tutoriels/off/290/le-concept-de-loriente-objet/#5-lheritage

Là, la question a été changée, et l'enchaînement n'est plus terrible  :D

Je n'ai plus trop de temps maintenant, je reviendrai par ici éditer ce message s'il n'y a pas eu de réponses ou en créer un autre le cas échéant.

Edit

Si si, je suis revenu, mais les messages suivants contiennent ce que j'aurais ajouté  ^^


  1. En fait, cette comparaison en nombre de lignes n'est pas pertinente, il vaudrait mieux regarder en taille de fichier de code, voire même en nombre de bytes utiles (on ne va pas tenir compte de l'indentation) 

+1 -0

Salut
Quelques remarques rapides au passage, j'essayerais de développer plus tard:
Je trouve que tu ne parles pas assez des concepts et que tu vas un peu vite vers l'implémentation (constructeur, classe abstraite,....). Il faudrait plus insister sur les concepts-clé de l'OO, décrits dans cet article par exemple: http://fr.wikipedia.org/wiki/SOLID_%28informatique%29

"Le but de la POO est simple, aller plus vite, pouvoir faire plus en écrivant moins.": là tu laisses penser que l'OO, c'est juste du code, alors que c'est surtout de la conception, de l'architecture.... On peut très bien penser objet, même avec un langage non objet.

Tu pourrais aussi développer la partie sur l'héritage multiple, et en quoi la notion d'interface permet de régler ces problèmes: http://fr.wikipedia.org/wiki/Probl%C3%A8me_du_diamant

Dans les années 60, il existait déjà l'impératif brutasse de l'assembleur. Il existait clairement le fonctionnel. Et il faudrait vérifier pour le déclaratif du Prolog – certes non mainstream. Toujours est-il que le procédural est loin d'être le seul paradigme majeur.

Le principe de fonctionnement de la POO est basé, comme dit plus haut, sur le fait que tout élément est objet et que chaque objet a un objet parent et éventuellement un objet enfant. Non, il n'y a pas forcément de parent, de même qu'il n'y a pas forcément d'enfant. C'est un détail.

L'objet, c'est d'abord un moyen de mettre en œuvre des services au travers d'abstractions, (via l'encapsulation), puis c'est une façon (dynamique?) de mettre en œuvre des points de variations (-> le polymorphisme d'inclusion, qui va s'appuyer sur l'héritage en effet)

La classe Personne que tu présentes est un très mauvais exemple de POO. Ce n'est qu'une agrégation de données, dans une syntaxe imposée par un langage à œillères OO. La différence que tu présentes avec du procédural ne se situe qu'au niveau du sucrage syntaxique de l'initialisation de l'agrégation. Elle ne touche pas les fondements de la POO. A la limite, on pourrait évoquer qu'un constructeur positionne l'invariant de la Personne, mais ce n'est pas l'objectif premier de l'OO. C'est un bonus important de beaucoup de langages OO, mais pas de tous je crains.

Si tu veux un exemple de différence entre la POO et le reste, c'est ceci qu'il faut regarder : http://fr.openclassrooms.com/forum/sujet/comment-le-c#message-87210210

J'insiste sur les setters : c'est l'antithèse de la POO : la prog orientée données. Les getters, ne provoquent pas des ruptures d'encapsulation aussi importantes quand les langages permettent un accès en read-only, mais ce n'est pas toujours le cas.

La vision de l'héritage est également trop technique à goût : orientée vers les fonctions mises à dispositions, et non vers la substituabilité qui est l'objectif majeur de l'héritage.

Concernant extends/implements, c'est de la bidouille technique Java qui passe à côté de la dualité de l'héritage qui est vraiment importante: substituabilité (cf LSP) VS import de code (sans substituabilité).

Bref, je dirai de reprendre les présentations. Si tu veux rentrer dans la technique, alors le tuto de conception devient un tuto de langage. Mais il y a déjà bien assez de choses à dire sur la conception OO, et de mythes à briser.

EDIT2: Tiens, j'avais manqué ça

Il existe même sur certains langages en OO (orienté objet) comme PHP, un destructeur qui sera appelé lors de la destruction volontaire (ou involontaire) de l'objet. Mais on utilise rarement cette méthode…

Les destructeurs sont juste la propriété du C++ qui fait toute la différence avec le C. Ce n'est certes pas une caractéristique fondamentale des langages OO (vu que peu en ont), mais c'est le moyen (déterministe et implicite) par lequel on finalise tout, sans exceptions. -> fichiers, mémoire, sockets, pots de peinture, … En Java, tu as le dispose-pattern (try+finally) (déterministe et explicite) et le try-with-ressources (?) depuis la v7.
Bref, les destructeurs sont au centre de ce que l'on appelle le C++ Moderne. C'est grâce à eux que l'on a des codes maintenables sans fuites ni rien. Donc, peut-être en PHP c'est le cas, mais en C++, on n'utilise certainement pas rarement les destructeurs. Bien au contraire on en use en permanence.
fin EDIT2

PS: Désolé si mon message peut paraitre "rude", il faut dire qu'il est tellement facile de s'arracher une jambe en C++ que l'on devient super tatillons sur la théorie qui l'on peut appliquer. ^^' Je sais que la tâche est rude. Bon courage.

EDIT: PPS: @Looping, ce que fait la notion d'interface, c'est qu'elle force aussi le respect du LSP. Et sans LSP il ne peut pas y avoir d'héritage multiple qui tienne la route.

Je continue ici, plutôt que d'éditer mon message.

On fait la différence entre propriétés et attributs en OO. L'attribut, est le détail invisible d'un objet qui permet de stocker son état. La propriété est une fenêtre vers une information que l'objet rend visible. On accepte pratiquement de violer (la loi de) Déméter dans le cas des propriétés, et donc de fournir des setters parfois. Mais pas nécessairement. De plus propriété ne veut pas dire attribut. Ex: l'âge d'une personne est une propriété, mais l'attribut sera très certainement la date de naissance. Et comme je le disais (mais non, je n'insiste pas! Si ? Vous croyez?) : transformer tous les attributs d'une classe en propriétés (getters + setters) est une erreur de design, et une faute de goût en violation avec les fondements de l'OO: offrir des services et autres abstractions.

Et non, l'objectif d'une méthode n'est pas de modifier un attribut. En revanche, une méthode va exploiter, et éventuellement altérer, l'état de l'objet sur lequel elle est appliquée pour faire rendre un service à l'objet. Bien sûr, l'état de l'objet est décrit/encodé par ses attributs propres ou hérités, directement ou indirectement, mais ceci est un détail.

Bonjour bonjour :)

J'ai eu un peu de temps et je me suis remis à bosser sur le tuto en prenant compte de vos remarques.

J'ai déjà changé la plupart des points donnés par ymox(btw aucune info supp sur la manière dont la poo a été fondée malheureusement).

Je suis actuellement sur ceux de Looping, et je me suis posé une question toute bête, dont j'aimerais avoir votre opinion. Où mettre SOLID? Je viens de mettre à jour la bêta, où j'y ai ajouté SOLID, mais en parler au début comme je l'ai fais n'à pas tellement de sens, puisque les notions de classes, d'abstractions, etc… ne sont abordés que plus tard dans le tutoriel. Le mettre à la fin semble aussi manquer d’intérêt puisque les concepts ont été évoqué précédemment. La meilleure solution serais peut-être de faire un titre récap à la fin? ;)

Il me reste encore beaucoup de changements grâce à vos conseils à faire, mais je m'y attelles dés que possible.

EDIT: si un de vous souhaite participer à la rédac du tuto ce serais apprecié ;)

+1 -0

Dans SOLID :

  • le SRP, c'est tout le temps (fonctions, classes, fichiers, libs, modules, boucles, …)
  • l'OCP et le LSP sont la raison et le quand du polymorphisme (d'inclusion, et pas que (pour l'OCP))
  • l'ISP n'est qu'un avatar du SRP appliqué aux interfaces
  • et le DIP, j'ai presque envie de dire que c'est une émanation de l'abstraction : on fait dépendre sur des types abstraits

Bref. Ce sont des principes intéressants, mais avant de les présenter, il faut expliquer ce que l'approche objet (cf mon exemple de lavage de linge), et ce qu'est le polymorphisme. Si tu analyses mes exemples (de mon 2e lien), tu verras qu'abstraction et service sont les concepts sous-jacents au premier exemple (et on retrouve indirectement donc le SRP : la blanchisserie ne propose que des services dans un thème très precis). Le second exemple est décrit en termes de points de variations (et le bonus de l'OCP y est décrit).
Le LSP interviendrait pour décrire le quand on peut hériter.

Bref, SOLID n'est pas la première chose à laquelle on pense. On pense soit d'abord à abstraire, soit on cherche à mettre en place des points de variations dans une opération. Ces deux objectifs vont nous amener vers la POO (dans les langages où on a le choix ; dans les langages à oeilières OO (Java, C#, Eiffel), il n'est pas rare de croiser des classes qui se contrebalancent de la philo OO (une présence élevée de setters ou de méthodes statiques est un indicateur du viol de la philo OO))

Il y a possibilité de les présenter au milieu des autres aspects (par exemple parler de LSP quand tu parles du polymorphisme) ou alors en faire un chapitre à part après (il y aurait d'ailleurs possibilité de faire un big-tuto (ou plutôt moyen-tuto), le format mini-tuto risque d'être rapidement débordé)

La première partie décrirait comme tu l'as fait, les concepts propres à l'objet (classes, héritage…) .Puis en deuxième partie, ce serait: maintenant qu'on a ces concepts, comment on les utilise? Et c'est là que SOLID intervient. C'est dans cette partie qu'on voit vraiment la philo objet, et qu'il faut bien montrer que l'objet, c'est pas juste du procédural avec des classes (c'est le truc le plus fréquent pour les débutants en C++ par exemple qui ne font que du "C avec des classes"). Ca pourrait être présenté de la manière suivante: pour chaque règle:

  • présenter une mauvaise conception de classes.
  • présenter la règle SOLID que cette conception enfreint, montrer les problèmes que ça peut générer.
  • et enfin présenter la bonne conception, qui respecte la règle.

Un exemple de présentation:
http://blogs.developpeur.org/fathi/archive/2011/11/26/pr-sentation-des-principes-solid.aspx
ou encore
http://philippe.developpez.com/articles/SOLIDdotNet/

Pour un début de piste sur pourquoi l'objet a été inventé:
http://rb.ec-lille.fr/recherche/Article_objet/httoc.html

Je vais faire court. Premièrement, je n'ai pas la forme question-réponse-dialogue entre l'auteur et le lecteur, style SdZ. Je ne trouve pas que cela rende la lecture plus agréable, mais par contre cela donne un aspect peu sérieux au tuto.

Et surtout, cela ne va pas dans le fond. On sent que le sujet n'est pas maîtrisé. Il y a beaucoup trop d'approximation, voire de choses fausses. L'organisation logique ne va pas non plus (parler de SOLID dès le début, comme si cela être trivial, pour revenir ensuite sur des bases de la POO, cela n'a pas de sens). Des remarques ont été faites, mais non pas été prise en compte. Le titre est "conception" alors que cela ne parle que de bases. Vision des objets orientées données et pas services. Voire une vision erronée de ce qu'apporte réellement la POO (pas simplement gagner quelques lignes de codes)

Cela n'est pas très grave d'écrire sur un sujet que l'on maîtrise pas, cela permet d'améliorer ses connaissances (et il y a suffisamment de relecteurs techniques pour signaler les problèmes). Par contre, cela demande un gros travail de recherche de références et de lecture. Le minimum est de faire apparaître les sources que vous avez utilisé en fin d'article (et s'il n'y en a pas, hum…)

+3 -0

Je surenchéris sur gbdivers pour dire que je trouve que votre présentation fait fouilli. Il y a des trucs à droite et à gauche sans lien logique apparent entre eux, et le tuto est résolument trop orienté mise en pratique : vous êtes censés parler de concepts, donc naviguer majoritairement dans le monde de l'abstrait ; pourtant, votre tuto manque lourdement de définitions précises et arrêtées (qu'est-ce qu'un objet, qu'est-ce que l'abstraction, etc.) et de vagues analogies avec le monde physique ne peuvent en tenir lieu. En outre, pour un cours théorique, il vous faut absolument bannir les formulations du type « dans la plupart des langages, on utilise ce concept via le mot-clé untel » : il serait beaucoup plus intéressant d'examiner comment l'un ou l'autre langage implémente les concepts généraux de la POO, les objets de JavaScript n'ayant pas grand chose à voir avec ceux de C++. Enfin, comme globalement tous les cours que j'ai lus jusqu'à présent sur la POO, vous ne parvenez pas à faire comprendre en quoi elle est utile en dehors de quelques cas restreints : en clair, pourquoi je devrais me faire chier à changer complètement de paradigme de programmation pour un système qui à première vue n'apporte que des contraintes supplémentaires ? Prenez peut-être exemple sur la programmation fonctionnelle : l'utilité du changement paradigmatique est beaucoup plus visible dans les textes qui en parlent.

+1 -0

Je n'avais aucune intention de upper ce sujet, je faisais juste une mini mise à jour du tuto qui à créé un nouveau sujet. J'ai d'ailleurs écris sur l'autre sujet que je n'avais pas eu le temps de prendre en compte tout les commentaires, mais ils n'ont absolument pas été ignoré. J'enlève le tutoriel de bêta et je le remettrait après l'avoir retravaillé. Merci pour vos commentaires en tout cas.

+0 -0

La vision de l'héritage est également trop technique à goût : orientée vers les fonctions mises à dispositions, et non vers la substituabilité qui est l'objectif majeur de l'héritage.

Concernant extends/implements, c'est de la bidouille technique Java qui passe à côté de la dualité de l'héritage qui est vraiment importante: substituabilité (cf LSP) VS import de code (sans substituabilité).

Tu confonds manifestement héritage et sous-typage. La substitution et le LSP concernent le sous-typage, alors que l'héritage est juste un mécanisme de réutilisation de code (généralement mauvais). Certes, les langages mainstream comme Java confondent les deux, mais ça n'est pas une raison pour le faire ici.

Sinon, les auteurs devraient probablement abandonner leur article, dont le sujet les dépasse manifestement.

Dans les langages mainstream, on ne peut effectivement pas sous-typer sans hériter – je ne connais pas assez les autres pour en parler. Et L'héritage ne sert pas à grand chose d'utile autrement que pour se donner le sous-typage. Et dans les premières ébauches de Kay, l'héritage n'a pas l'air d'avoir une grande place.

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP.

Oui c'est vrai, Alan Kay a regretté à plusieurs reprises d'avoir formulé la programmation orientée objet comme il l'a fait, ainsi que l'interprétation que les différents auteurs de langages (Java, C++…) en ont fait par la suite.

Encore une fois, si les auteurs avaient initialement prévu de mentionner ce genre de réflexion, j'aurais été le premier à les soutenir, mais je pense que sinon cet article n'en vaut pas la peine.

(Merci pour les -1 sur le message précédent. Si vous ne savez pas ce que c'est le sous-typage, vous n'êtes pas obligés de me moinsser, vous pouvez aussi poser des questions, ou aller chercher sur Wikipédia.)

C'est plus ta définition de héritage qui me gène en fait. Parce que "mécanisme de réutilisation de code" m'embête. Souvent, quand je commence à parler d'héritage, je n'ai pas encore fait la moindre ligne de code. L'héritage n'est qu'une relation de généralisation/spécialisation (selon le sens de lecture). Les traits/mixins sont eux des mécanismes de réutilisation de code. L'héritage n'en est pas et l'utiliser comme tel entraîne souvent des mauvaises utilisations.

Ça n'est pas ma définition, c'est pour partager du code que l'héritage a été introduit, et certains langages (comme OCaml) font la différence entre héritage et sous-typage, d'autres non. Comme tu le dis toi-même, il existe de meilleurs mécanismes de réutilisation du code, mais ils ne sont pas toujours disponibles.

Souvent, quand je commence à parler d'héritage, je n'ai pas encore fait la moindre ligne de code.

Comme l'a dit lmghs, ça n'est pas surprenant puisque la pratique de langages comme Java et autres fait que c'est passé dans les mœurs. Mais ça n'est pas l'origine du concept, et confondre les deux notions, c'est aller à l'encontre des travaux théoriques qui ont été faits dessus, et s'éloigner des définitions originales.

Comme tu le dis toi-même, il existe de meilleurs mécanismes de réutilisation du code, mais ils ne sont pas toujours disponibles.

Une nouvelle fois, je ne suis pas d'accord. L'héritage est une notion qui vient de l'activité de conception. Quand tu conçois, un peu comme dans le cadre de certaines de nos ZEP, tu n'as pas encore écrit le moindre bout de code que tu crées des relations.

Et force est de constater que 2 relations font tout dans le monde de l'OO : la délégation et la généralisation/spécialisation (sens de lecture, tout ça). L'héritage n'est qu'une implémentation de la spécialisation (pas de sens de lecture possible), je ne sais pas s'il y en a d'autres, je ne les ai pas toutes étudiée, mais l'héritage c'est avant tout ça.

par contre, quand j'entends parler traits/mixin je viens remplacer le copier/coller par une notion logicielle.

Je ne dis pas que l'héritage est le sous typage c'est la même chose, je commence à être trop bien familier avec le principe de Liskov et la substitution pour faire cette erreur, par contre je dis que l'héritage n'est pas un mécanisme de récupération de code.

+1 -1

Je comprends ce que dis Katana. Et cela rejoint une chose qui me gêne dans les langages OO mainstream (et en particulier Java) qui mette l'accent sur la chose la moins pertinente, relativement à l'héritage. Il faut dire que ce que je recherche dans l'héritage, c'est le sous-typage avant tout. Car c'est le moyen de l'obtenir (en C++ que je pratique principalement). Et c'est là que j'avais bien aimé ruby qui distingue le sous-typage et l'importation de code.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte