CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[Encapsulation]Je ne comprend pas...

Lagrangien
Lagrangien
Niveau 8
07 octobre 2012 à 23:22:02

Salut,

Dans tous les cours que je trouve sur la programmation (mes cours concernent néanmoins le langage C++), il y a un son de cloche invariable à l'ouverture du chapitre sur les classes : les attributs d'une classe doivent être privés (ou au moins protected).

Sur le site du zéro, c'est même écrit en rouge et en grande taille : http://www.siteduzero.com/tutoriel-3-11167-les-classes-partie-1-2.html#ss_part_2

Sur d'autres sites, on explique le pourquoi de la chose :

commentcamarche.net :
"L'utilisateur d'une classe n'a pas forcément à savoir de quelle façon sont structurées les données dans l'objet, cela signifie qu'un utilisateur n'a pas à connaître l'implémentation. Ainsi, en interdisant l'utilisateur de modifier directement les attributs, et en l'obligeant à utiliser les fonctions définies pour les modifier (appelées interfaces), on est capable de s'assurer de l'intégrité des données (on pourra par exemple s'assurer que le type des données fournies est conforme à nos attentes, ou encore que les données se trouvent bien dans l'intervalle attendu)."

wikibooks :
L'avantage de cette restriction est qu'il empêche par exemple un utilisateur de la classe de mettre les données dans un état incohérent. Vue de l'extérieur, la classe apparaît comme une boîte noire, qui a un certain comportement à laquelle on ne peut accéder que par les méthodes publiques. Cette notion est extrêmement puissante et permet d'éviter de nombreux effets de bord.
L'encapsulation permet de distinguer très nettement ce que fait la classe et sa sémantique précises de la manière dont on l'implémente. Cette réflexion permet de répondre dans un premier temps à la question Comment utilise-t-on la classe ? Ce n'est que dans un second temps que l'aspect technique entre en jeu et que le programmeur doit répondre à la question Comment vais-je programmer les fonctionnalités de la classe qui ont été spécifiées ? L'encapsulation permet de faire abstraction du fonctionnement interne (c'est-à-dire, l'implémentation) d'une classe et ainsi de ne se préoccuper que des services rendus par celle-ci.

Mais j'ai beau fouiller à gauche à droite, je me pose toujours cette question : Pourquoi ?

Imaginons que moi et mon ami imaginaire génial, nous fondions une boite de programmation pour développer des logiciels. Nous développons une librairie que nous sommes les seuls à utiliser. Pourquoi devrait-on mettre les attributs des librairies de ces classes en private ? Serais-ce uniquement pour ne pas se tromper, et ne pas donner une valeur à un attribut censé ne jamais prendre cette valeur ?
D'ailleurs, j'ai remarqué que dans la librairie SDL, de nombreux attributs de classes (la classe SDL_Rect par exemple) sont publics et modifiables sans restriction par l'utilisateur.

Autre question : le leitmotiv prôné par le SDZ me semble excessif pour une autre raison. Imaginons que dans une classe, j'ai un attribut qui est un int et qui n'a AUCUNE restriction sur la valeur qu'il peut prendre (si ce n'est la restriction qu'il doit être entier, puisque c'est un int, mais dans ce cas de toute manière le compilateur le signalerait à la compilation).
C'est un peu e*culer une mouche que d'écrire un getter et un setter pour cet attribut, non ?

tbop2
tbop2
Niveau 10
08 octobre 2012 à 10:46:04

Salut,

Il est tres bien en effet de remplacer ca dans un contexte de groupe car c'est aussi la le point fort de l'encapsulation : securiser tes donnees. L'autre point fort c'est aussi de t'efforcer a concevoir toute l'architecture de ton programme comme une propre interface utilisateur, e.g. tu fais une classe pour un but precis, avec des methodes tres simples avec des noms comprehensibles qui sont facilement utilisables par n'importe quel abruti (pour caricaturer (mais pas tellement en fait)). TOUT EST INTERFACE (c'est le point important), tout doit etre aussi simple qu'une boite fonctionnelle.
Je suis aussi conscient que ce concept puisse echapper a quelqu'un qui n'ait jamais fait de la programmation car pour lui : "le monde il est tout beau, le monde il est tout parfait, les maths s'arretent au niveau Seconde et le code tient en 1 000 lignes d'instructions". Tu comprendras vite avec le temps, avec l'experience en travaillant avec des codes qui ne t'appartiennent pas, en donnant a des gens un code qu'ils ne connaissent pas... ou tout simplement en debuguant ou en ecrivant des unit tests.
Ce concept est difficilement assimilable a ce stade la de l'apprentissage... et encore moins sur un site comme le SDZ hum hum.
Pour le moment je te conseille d'imaginer un code source qui fait un truc un peu complique et pas forcement intuitif, disons par exemple un crypteur SHA-1 par exemple. Toi ce que tu esperes quand tu telecharges le code source (open source!) c'est qu'il y ait le minimum de methodes et le minimum d'effort pour arriver a tes fins. Si le createur originel mettait tous les tenants et aboutissants qui se trament dans le SHA-1 tu resulterait en une interface qui :
- est 10 fois plus grosse
- 10 fois moins stable car totalement transparente
- 10 fois plus compliquee a comprendre pour celui qui l'utilise

En ce qui concernant la SDL c'est un librairie C donc la POO n'est pas entierement realisable dans ce langage.

Lagrangien
Lagrangien
Niveau 8
08 octobre 2012 à 12:37:17

D'accord, donc en gros, quand on fait un modeste programme pour soi-même et uniquement pour soi-même, mettre tous les attributs d'une classe en private, c'est juste pour prendre la bonne habitude de le faire...

Donc tu confirmes que le gros intérêt de l'encapsulation est plus "logistique", "pratique", que purement "programmationnel" ?

(Et dans mon monde, les maths sont très loin de s'être arrêtées en seconde ... : D )

tbop2
tbop2
Niveau 10
08 octobre 2012 à 13:32:59

Oui Lagrangien j'aurais du m'en douter que t'etais un peu plus loin que la terminale S... :P

Non non l'encapsulation est tout a fait programmationnelle aussi. Comme je l'ai dit exposer un attribut c'est prendre le risque non-negligeable des effets de bords et il faut poser la question dans l'autre sens, non pas "mais pourquoi je ne peux pas mettre cet attribut public" mais plutot "Why the hell on earth je devrais avoir besoin de modifier ce truc a l'exterieur de ma classe elle-meme???".
C'est tout aussi tres pratique pour debugguer simplement, hop un breakpoint dans le setter et tu sais quand est-ce que ton attribut est modifie.
C'est aussi totalement essentiel pour les unit tests, tu ne veux pas t'embeter a gere des cas ou tu modifies des trucs qui ne devraient pas etre modifiables dans tes unit tests. C'est d'ailleurs dans les unit tests qu'on voit generalement si son code est stable, propre, et strictement utilisable dans les limites qu'il lui est impose. Tu sais ecrire du code c'est ecrire des bugs, il n'y a jamais assez de securites pour ca (d'ou le "le monde il est tout beau il est tout propre). Du code sans bug CA N'EXISTE PAS ! (sinon on ne travaillerait pas)

Il faut voir le code comme Google Earth un peu, plus tu zoomes, plus tu as des details, plus tu as de fonctions ... et plus les informations visuelles sont complexes a gerer aussi. A chaque classe sa responsabilite, etre responsable c'est faire une chose precise a la fois et s'assurer que personne n'empiete sur ton territoire.

J'espere que ces metaphores seront plus parlantes. Je t'assure que tu comprendras tres vite les dangers de la non-encapsulation bientot avec des codes plus fouillees, et meme ton propre code.

godrik
godrik
Niveau 30
08 octobre 2012 à 15:24:36

Lagrangien, l'un des interets principaux de l'encapsulation est de ne pas avoir de variable qui change de valeur sans que tu le sache. Dans la plupart des applications, une variable ne peux pas prendre toutes les valeures possible, certainement chose ne peuvent pas etre negative, un pourcentage est entre 0 et 100... Utilser l'encapsulation permet de faire attention a ces choses la.

Aussi dans certain cas, il est important de conserver la coherence de certaines variables. Par exemple, dans un RPG, quand HPmax diminue, il faut ajuster HP de la meme maniere. Ou au contaire, quand HP augmente, il ne peux pas depasser HPmax. L'encapsulation, ca sert aussi a gerer ces choses la.

Nightmarez
Nightmarez
Niveau 9
08 octobre 2012 à 17:35:07

D'apres les avis que j'ai pu voir sur le net, la tendance veux que dans le cas ou tu cherches a controler la modification de donnees (par exemple pour faire du rangecheck ou comme dit godrik dans le cas des points de vies), il faut absoluement un setter, mais j'ai aussi lu des articles ou ils disaient que les getters et setters qui ne font rien mais qui sont la juste parce que ca fait plus objet etaient loin d'etre utile.

Comme dit plus haut, c'est vraiment dans la necessite de controler ou non les acces a ta donnee.

godrik
godrik
Niveau 30
08 octobre 2012 à 17:52:10

il y a des jours ou tu utilise des classes juste pour des facilite d'ecriture. Par exemple, j'ai souvent une classe qui stocke les coordonnes d'un point dans le plan. Ca n'a aucun interet de mettre les coordonnes en prive et d'encapsuler ce truc la.

(certains vont dire que ca a un interet si tu veux avoir des coordonnees polaire et cartesienne, mais une conversion de type est certainement plus approprie dans un cas pareil.)

Lagrangien
Lagrangien
Niveau 8
08 octobre 2012 à 19:17:38

"mais j'ai aussi lu des articles ou ils disaient que les getters et setters qui ne font rien mais qui sont la juste parce que ca fait plus objet etaient loin d'etre utile. "

"Par exemple, j'ai souvent une classe qui stocke les coordonnes d'un point dans le plan. Ca n'a aucun interet de mettre les coordonnes en prive et d'encapsuler ce truc la. "

Voilà exactement ce que je voulais dire. Donc c'est une opinion un peu extremiste de dire que TOUT attribut doit TOUJOURS être privé, façon SDZ^^

Pour le reste, je comprend bien que dans la majorité des cas c'est une bonne chose de garder le contrôle sur les attributs via les setters.

Aldebran
Aldebran
Niveau 10
08 octobre 2012 à 19:33:48

"mais j'ai aussi lu des articles ou ils disaient que les getters et setters qui ne font rien mais qui sont la juste parce que ca fait plus objet etaient loin d'etre utile. "

C'est souvent une question de clarté et de cohérence du code : de ce point de vue là c'est plus pour des raisons esthétiques qu'autre chose. Mais il y a un autre avantage : si jamais tu décides en cours de développement qu'un utilisateur de tes classes ne doit pas pouvoir simplement setter ta variable (car tu as désormais des contrôles à faire pour vérifier qu'elle est conforme) ; si toutes les occurrences de code servant à définir cette variable utilisait un setter, alors tu as juste à modifier ton setter, mais si tu accédais directement à ta variable, alors tu dois remplacer toutes les occurrences d'accès direct à la variable et les remplacer par un setter au préalable.

A noter que dans un langage comme Java, il m'arrive de définir des attributs en publiques pour les raisons qu'a cité Godrik (représentation de points, de vecteurs, etc.). Mais dans un langage comme C#, je définis systématiquement mes getters et mes setters : C# propose une syntaxe spécifique pour définir les getters et les setters relativement pratique et claire pour l'utilisateur final de la classe (du moins à mon sens, il y a des gens qui n'aiment pas et qui ont l'impression que les accesseurs sont un peu "cachés" par cette syntaxe).

Bunyan
Bunyan
Niveau 17
08 octobre 2012 à 20:55:53

Il y a un autre souci de cohérence : générer/faire les accesseurs pour chacune des variables-membres est inutile. Beaucoup de ces variables sont pour la tambouille interne de la classe, et ne devrait pas être révélée/accédée/modifiable.

Le fait de mettre en privé le tout, n'implique en aucun cas de mettre des accesseurs partout (l'utilité du privé est presque totalement détruit ainsi).

hyrulink2
hyrulink2
Niveau 7
08 octobre 2012 à 21:34:52

Au début c'est bien de tout mettre en privé pour prendre l'habitude.

Mais ça ne sert à rien dans le cas d'une classe qui sert juste à agréger des valeurs et ne contient aucune intelligence et où les donnés n'ont pas de lien entre elles comme std::pair, une coordonnée comme dit plus haut, une classe qui ne représente que des attributs non corrélés et dont le fonctionnement est géré par une autre classe englobante de manière générale.
D'ailleurs dans ce cas là on aura plutôt tendance à utiliser struct plutôt que class pour bien expliciter "ça c'est juste des données brutes".

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment