Questions sur des termes POO

Le problème exposé dans ce sujet a été résolu.

Faire le distingo attribut/méthode, ça me parait pas capital.

@Adri1 :D’après moi ,après j’ai peut être tort mais une méthode est censé représenter une fonctionnalité ,donc le vrai débat serait de dire est ce que un getter ou un setter est vraiment une méthode parce que c’est équivalent la plupart du temps à mettre directement l’attribut en question en public et non en privé.

+0 -0

parce que c’est équivalent la plupart du temps à mettre directement l’attribut en question en public et non en privé.

Personnellement il m’arrive souvent d’avoir des getter, moins des setteurs. En effet le fait que ce soit disponible en lecture seule vis à vis de l’extérieur est souvent utile et rarement proposé nativement par les langages.

Et un setter peut aussi vérifier ou travailler la valeur en entrée avant de l’appliquer sur l’attribut. Cela peut être utile pour garantir la validité de l’objet.

+0 -0

Avoir un attribut, c’est une fonctionalité.

Maintenant, on s’en fout pas mal parce qu’une interface définit un comportement. Que ce comportement implique seulement des méthodes ou aussi des attributs ou encore autre chose, ce sera dépendant du langage dans lequel l’interface en question est définie. Dans tous les cas, c’est un détail qui n’est pas capital pour comprendre les relation entre classe, interface, et implémentation.

Je suppose que la distinction méthode/attribut est importante dans les langages où on ne peut pas surcharger les attributs – et qui donc ne peuvent généralement pas avoir d’attributs dans les interfaces.

SpaceFox

En effet, si on peut pas surcharger les attributs, les mettre dans une interface n’a aucun sens.

Ma définition d’interface est large également, et nullement contrainte par la caverne Java/UML. Je prends la définition du C++: tout ce qu’un code client peut opérer sur un objet, d’une certaine façon, c’est son interface. Je n’hésite pas à prendre des latitudes car après tout, ni Java ni C++ ne sont OO d’après Alan Kay à qui on doit le terme "OO". La notion d’interface n’y existe pas non plus.

Après, on peut documenter: "ça, n’y touche pas, il n’y a pas de garantie de stabilité/pérennité". Chose qui à conduit à l’expression plus formelle de l’interface en Java.

Dans mon appréciation, les attributs publics appartiennent à l’interface, de sont des propriétés sans le décorum getter/setter.

J’ai tendance à considérer qu’abstraction et interface, c’est un peu la même chose: on se concentre sur la partie stable et utilisable d’un code, et non sur le comment.

PS: j’ai vu passer quelques mots sur les setters. Je suis de plus en plus convaincu qu’il s’agit d’un anti pattern objet. Car: Si le setter fait plus que positionner, son nom devient un mensonge: le verbe n’est plus correct, il doit être complété. Aussi, comment gérer les cas d’invariants impliquant plusieurs attributs. Pour reprendre une de mes proses récentes:

Imaginez une classe de nombres rationnels dont l’invariant est "PGCD(num, den) == 1, et den > 0". Qu’à un instant donné on a une instance qui vaille 1/2 et que l’on veuille avoir à la place 4/3. Si on enchaînes les opérations r.setNum(4), r.setDen(3), on a alors toutes les chances de se retrouver avec 2/3 au lieu de 4/3 si les setters prennent en charge la garantie des invariants. Ouch! Pourtant ils encapsulent bien…

PPS: qu’entendez-vous par "surcharger un attribut"? override? ou overload? Quelles en seraient les conséquences, les possibilités?

Bon déjà merci à tous pour vos réponses ,je vais essayer de synthétiser ce qui a été dit ,dites moi si j’ai bien compris :
Déjà pour la notion d’interface :
- Dans le cadre de la poo théorique il s’agit d’un ensemble de signature de méthodes permettant de manipuler un "type".
- Il existe aussi une version plus générale de la notion d’interface qui prend en compte tout ce qui est dans la portée publique c’est à dire méthodes + attributs + tout autres fonctions permettant de manipuler l’objet en question (fonction libre , opérateurs …)
Donc si on reformule de premier principe cela devrait donner :
Programmez des classes abstraites ou des interfaces(au sens de Java) ,pas des implémentations.

Pour la notion d’abstraction son interprétation dépend de son contexte , car il y a différents niveaux d’abstractions : la classe est une abstraction d’un concept , et l’interface (au sens POO du terme ) est une abstraction d’une classe.
Du coup si on reformule le deuxième principe cela devrait donner :
Les modules de haut et de bas niveaux ne devraient pas dépendre de détails d’implémentation(classes concrètes) mais de classes abstraites ou d’interfaces (au sens Java )

Voilà j’espère n’avoir rien oublié , si j’ai dit une bêtise n’hésitez ou oublié quelque chose n’hésitez pas à me de le dire.

PS : Et je tenais à m’excuser pour l’accrochage qui eu lieu en début de post .

+0 -0

J’ai l’impression que ce que tu appelles « POO théorique » c’est « POO selon Java », parce que je ne vois pas pourquoi il y aurait une différence de définitions entre « POO théorique » et « version plus générale ».

Je pensais que la poo "théorique" ne s’intéressait qu’au paradigme objet et pas au paradigme fonctionnel , et que donc en terme de poo "théorique" on aurait idéalement que des classes et pas de fonction libre par exemple et que donc est que dans ce cadre là dire qu’une fonction libre fait partie d’une interface aurait du sens ?

+0 -0

Mais ça encore une fois c’est plutôt propre au style Java.

Déjà, les classes ne sont pas nécessaires pour faire de la programmation objet. Mais pour les langages qui en disposent, des fonctions hors de toute classe peuvent s’inscrire dans une conception objet (une fonction statique main n’a pas d’intérêt particulier à être intégrée dans une classe, par exemple).

Et paradigmes fonctionnel et objet ne s’opposent pas nécessairement, jette un œil à l’OCaml par exemple.

Je pensais que la poo "théorique" ne s’intéressait qu’au paradigme objet et pas au paradigme fonctionnel , et que donc en terme de poo "théorique" on aurait idéalement que des classes et pas de fonction libre par exemple et que donc est que dans ce cadre là dire qu’une fonction libre fait partie d’une interface aurait du sens ?

Octodex

Plusieurs problèmes.

La "définition" historique de l’OO est assez éloignée de ce qui est pratiqué dans les langages mainstreams qui disent supporter l’OO. Kay regrette d’ailleurs d’avoir utilisé le mot "object" car les gens ne se sont pas concentrés sur la chose importante : la communication. De plus, presque on pourrait dire que Java & cie sont en fait orientés classes. Or c’est limite contraire aux fondements même de l’OO de Kay. Avec les interfaces java/UML, nous sommes en plein typage, et donc en pleine contradiction avec la flexibilité ultime du "extreme late-binding of all things".

Aussi, si les langages OO mainstream ont une base procédurale, un des langages les plus OO selon Kay était CLOS qui lui a une base LISP et donc totalement fonctionnelle. Les principes OO sont orthogonaux à procédural/fonctionnel.

Et d’un point de vue tout à fait pragmatique, en presque 10 ans de carrière et beaucoup plus de projet, je n’ai jamais vu de code qui respecte mieux que « vaguement » les principes de la « POO telle qu’elle devrait être selon le cours » (le tout généralement appliqué à Java, mais pas que).

Autant te dire que pour ce qui est de respecter l’OO « historique », on est carrément dans le fantasme.

(mon avis personnel est qu’on devrait avoir des machines à états qui communiquent entre elles, mais je suppose qu’on s’éloigne du sujet. Mais j’aime bien les machines à états)

Merci pour vos réponses détaillées , @lmghs et @SpaceFox ,je prends note. (Même pour la machine à états ;) )

Donc si je reprends avec les modifications que vous m’avez indiquées : Pour le premier principe cela pourrait être équivalent à dire que l’on doit assurer les fonctionnaltés exposées par l’interface au sens large , sans s’occuper du comment.
Pour le deuxième principe on pourrait dire que les modules de haut et bas niveaux devrait dépendre d’une abstraction c’est à dire d’une d’une classe mère (abstraite ou non) (Car elle pourrait être considérée comme une abstraction de sa classe fille ).
Désolé si je suis un peu lourd mais je veux comprendre ,donc j’insiste un peu

+0 -0

J’ai tendance à résumer la programmation orienté objet, de manière la plus générale, comme :

La description d’un programme par :

  • Un ensemble d’agents pouvant chacun recevoir différents messages et y réagir :
    • En émettant de nouveaux messages
    • En générant de nouveaux agents
  • Un ensemble de messages initiaux

C’est probablement un peu naif comme vision, peut-être trop générique (voir pouvant inclure des choses étrangères à la POO). Mais ca m’a toujours suffit pour appréhender les différents principes et réflexions sur la POO, dans un cadre suffisamment large et avec un vocabulaire éloigné de la plupart des langages.

Si je reprends les principes SOLID, par exemple :

  • Single Responsibility Principle : Un agent ou un message n’a qu’un seul rôle, tu dois pouvoir le résumer en une phrase simple
  • Open Closed Principle : De nouveaux messages peuvent être ajouté à un agent, mais le rôle d’un message ne peut être modifié
  • Liskov Substitution Principle : Un agent peut être substitué par un autre si il peut recevoir les mêmes messages
  • Interface Segregation Principle : L’ensemble des messages auxquels un agent peut répondre doit être le plus petit possible
  • Dependency Inversion Principle : La réponse à un message doit être formulée en fonction d’autres messages, pas d’agents particuliers

Par dessus, on pourrait rajouter quelques éléments :

  • Si deux agents acceptent un même groupe de messages, ce groupe forme un contrat
  • De plus si ce groupe est exclusif et que les agents y répondent de la même façon, ils sont de la même espèce
  • Si le groupe de messages d’une espèce est inclus dans le groupe d’une autre, alors la seconde est une sous-espèce de la première

Si tu prends un langage particulier, tu vas retrouver les agents/messages/espèces/contrats/sous-espèce avec une autre terminologie. Pas forcément les quatre, et surtout, un langage ne va que fournir les outils, mal utilisé ils ne vont pas du tout refléter une vision orienté objet.

Par exemple, en C++, un agent est un objet (au sens de la norme, un espace mémoire avec un type), une classe est une espèce, une classe fille est une sous-espèce. Les messages sont tous ce qui est accessible : fonctions (libres ou liées publiques) et les attributs publiques. Et j’ai pas assez suivi les dernières avancées du C++ pour dire si il y a des contrats ou juste sous une forme affaiblies.

PS: Ce n’est qu’un point de vue, sujet à critique et discussion.

+4 -0

Pour illustrer, disons qu’on est dans un cas où la définition d’un message inclut les espèces/sous-espèce/contrat, des agents que le message va notifier (c’est la signature d’une fonction pour certains langages). Dans ce cas, une implication du DIP, c’est d’utiliser les contrats dans la signature et rien d’autre.

Par exemple, si tu as une espèce TCP et que tu as un message qui utilise un agent de cet espèce pour communiquer : foo(TCP protocol). Le DIP va te dire de plutôt abstraire cette espèce en ne pensant ton message foo que comme un message utilisant un protocole de communication, peu importe que ce soit TCP ou UDP (ou autre). Tu vas donc avec un contrat Protocol et ton message devient : foo(Protocol protocol). Et les espèces TCP et UDP qui respectent ce contrat.

Si on prend des langages qui proposent des classes et des classes abstraites uniquement. Ca se traduit par une classe abstraite Protocol, deux classes filles TCP et UDP. Et la fonction foo(Protocol protocol). Tu dépends de l’abstraction de la notion de protocole, et non d’une réalisation particulière.

Au final les implications sont les mêmes que celles que met en avant Davidbrcz au début du sujet.

+1 -0

@Octodex : il y a une analogie que j’aime bien par rapport au DIP et au OCP :

Imagine toi que tu es un fabriquant de télévision qui ne respecte ni l’un ni l’autre

Tu as donc une télé, qui sait afficher une image, chouet.

Mais maintenant, tu veux pouvoir jouer à ta console de jeux vidéo. Du coup, comme elle ne respecte pas le principe "overt/fermé" il va falloir que tu aille trifouiller ta télévision pour que la console puisse être utilisée.

De même lorsque tu voudrais utiliser un lecteur DVD ou blue ray (paraît qu’on est en 2018).

Et puis un jour tu vas vouloir afficher une image HD, voire 4K, donc il va falloir trifouiller ta télévision etc.

Le OCP te dit que tu vas cacher comment est faite ta télé, par contre tu vas lui fournir un ensemble d’entrée (une interface) avec laquelle elle pourra discuter. Une entrée VGA, HDMI, DP, antenne par exemple. De plus tu vas lui ajouter une prise interne à laquelle sera branché un décodeur TNT, qui lui connaîtra un ensemble type de "message" : le protocole DVB dans différente version par exemple.

Ce tunner ne doit pas réagir différement en fonction du message lui-même, mais du protocole du message (tiens, encore une interface). En gros le tuner n’a pas été créé en fonction du nombre de chaîne au moment où il a été fabriqué, ni même en fonction de la dynamique des programmes (un film d’action est plus dynamique qu’un documentaire animalier en terme de colorimétrie par exemple) on lui a dit "DVB" c’est X choses à respecter, si tu les respectes c’est bon.

Et maintenant peu importe le nombre de chaînes, la dynamique des programme ou la résolution, du moment que ton tunner est compatible avec la version du DVB actuelle, tout est ok.

Le DVB ne dépend pas des tunner, d’où le concept "d’inversion de la dépendance".

Dans nu contexte "agent", l’OCP je vois plus ça comme la possibilité de plugguer/injecter un agent compatible à un protocole établi sans induire de devoir modifier le protocole. En termes bassement techniques, pas de if ni switch, mais des points de variation ouverts.

D’autres analogies pour SOLID ont été énoncées ici: http://www.arolla.fr/blog/2017/02/principes-solid-vie-de-jours/ J’adore celle pour Déméter.

En termes de formulation pour une définition de l’OO, j’aime bien celle de Cook, mais elle est particulièrement ardue à déchiffrer: http://wcook.blogspot.fr/2012/07/proposal-for-simplified-modern.html

Tiens, sur le sdzoc, il y avait eu une discussion intéressante où Ksass`Peuk qui a as mal réfléchit sur le sujet fait un bon résumé des définitions sur l’OO: https://openclassrooms.com/forum/sujet/novice-en-poo-par-quoi-commencer
Cela suivait en parti des discussions tenues ici même: https://zestedesavoir.com/forums/sujet/6264/les-principes-solid/?page=2#p147628

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