IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langages de programmation Discussion :

Ce que vous l'on vous a enseigné sur la POO est conforme avec la réalité


Sujet :

Langages de programmation

  1. #1
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut Ce que vous l'on vous a enseigné sur la POO est conforme avec la réalité
    La "bonne façon de faire" ne me semble pas la meilleure.

    Je suis tomber sur une vidéo. Et le type expliquait qu'il ne fabriquait pas des accesseurs que si c'était absolument nécessaire. Et n'utilisait jamais la directive Private. Est-ce différent de l'enseignement que vous avez reçu? Ayant débuté la programmation-object sur Pascal, j'ai toujours trouvé bizarre cette fabrication systématique d'accesseurs. Je crois que cette pratique est ce qui pénalise le plus la performance des programmes en C++ (en excluant l'héritage)



    La gestion étroite de la mémoire avec le tas et la pile est-elle encore justifable pour des applications ?

  2. #2
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Citation Envoyé par Madmac Voir le message
    Est-ce différent de l'enseignement que vous avez reçu?
    En école d'ingé, on m'a introduit la POO avec Java. Ensuite, au boulot, quand je faisais de la POO, c'était en C++ et en Python.

    Quand j'étais en école d'ingé, en Java, on nous demandait de rendre privées les variables membres et de coder des accesseurs publics et des mutateurs publics. Un grand classique était de coder une classe Point. Les champs privés étaient les coordonnées cartésiennes. Il fallait passer par des accesseurs getX et getY pour les lire et des mutateurs setX et setY pour les modifier. On nous vendait alors que, grâce à ça, si on voulait changer la représentation et remplacer les coordonnées cartésiennes par des coordonnées polaires, il n'y avait pas besoin de changer le code appelant, seulement celui de la classe Point.

    En pratique, en Java, il vaut souvent mieux privilégier les classes immuables, donc supprimer les mutateurs, mais c'est un autre sujet.

    Citation Envoyé par Madmac Voir le message
    Revenons à l'exemple d'une classe Point muable avec des coordonnées cartésiennes. Dans l'argumentation du YouTubeur que tu cites, rendre systématiquement privées les variables membres et introduire des accesseurs getX et getY et des mutateurs setX et setY, c'est une forme de YAGNI. Ce YouTubeur demande d'attendre que les accesseurs et mutateurs fassent quelque chose de plus compliqué avant de les introduire.

    Je suis d'accord avec cette argumentation quand on a la main sur le code appelant (ce qui n'est pas le cas, par exemple, des auteurs de bibliothèques qui rendent accessibles ces dernières à des utilisateurs).

    Mais ce YouTubeur suggère qu'il n'utilise jamais ou presque jamais private. Je ne sais pas ce qu'il code mais, dans mes programmes, j'ai souvent des données accompagnées de contraintes (ex : telle valeur doit être strictement positive) et je les encapsule dans des classes qui garantissent ces contraintes. Je passe par des invariants de classe qui ne peuvent être garantis que si j'utilise private.

    Il y a aussi des cas où mes classes n'offrent aucun accès direct aux membres (pas de getTheMember ni de setTheMember), car ces membres sont des détails d'implémentation. Les premiers exemples qui me viennent en tête sont ceux où j'avais codé un wrapper par dessus une classe fournie par une bibliothèque externe, afin de minimiser la quantité de code qui dépendait de cette bibliothèque externe.

    Citation Envoyé par Madmac Voir le message
    Ayant débuté la programmation-object sur Pascal, j'ai toujours trouvé bizarre cette fabrication systématique d'accesseurs. Je crois que cette pratique est ce qui pénalise le plus la performance des programmes en C++ (en excluant l'héritage)
    Non. En C++, si tu écris un accesseur très basique ou un mutateur très basique directement dans le ".h", il n'y aura pas de baisse de performance en mode release, car le compilateur va optimiser en remplaçant l'appel de la fonction par le code de cette dernière (c'est l'inlining). Pour l'héritage, ça dépend des cas. Par exemple, le CRTP n'introduit pas de pointeur vers une table virtuelle dans la classe dérivée.

    Citation Envoyé par Madmac Voir le message
    La gestion étroite de la mémoire avec le tas et la pile est-elle encore justifable pour des applications ?
    Je ne vois pas le rapport avec les accesseurs et les mutateurs. Mais, pour répondre à ta question, si on veut maximiser les perfs, oui, il faut gérer la mémoire pour minimiser les allocations dynamiques inutiles et les cache miss.

  3. #3
    Membre régulier
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Août 2018
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur validation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2018
    Messages : 37
    Points : 123
    Points
    123
    Par défaut
    Si les accesseurs et mutateurs sont de simples passe-plats qui n'effectuent aucun contrôle, ni aucune transformation entre l'attribut privé et ce qui est exposé par l'interface publique, l'encapsulation n'apporte effectivement pas grand chose. Il manque d'ailleurs au C++ les formes assez élégantes des properties où l'on peut implémenter, si besoin, un accesseur et/ou un mutateur spécifique, et dont l'appel est transparent pour le code client (il y a cependant des développeurs C++ farouchement opposés aux properties).

    Mais, pour paraphraser Pyramidev, une classe peut manipuler beaucoup d'attributs qui n'ont pas à être exposés publiquement, juste pour son fonctionnement interne.

    Le souci du C++, c'est que ces membres privés (attributs, tout comme les fonctions) doivent tout de même être déclarés dans le header et sont visibles par le code client.
    Et si on change les détails d'implémentation sans bouger l'interface, le code client doit être inutilement recompilé.

    Il y a l'idiome Pimpl, qui permet de cacher ces détails dans une classe d'implémentation privée. Mais ça pèse sur les perfs puisqu'il faut accéder aux membres privés par une indirection.

  4. #4
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par Grool Voir le message
    Le souci du C++, c'est que ces membres privés (attributs, tout comme les fonctions) doivent tout de même être déclarés dans le header et sont visibles par le code client.
    Et si on change les détails d'implémentation sans bouger l'interface, le code client doit être inutilement recompilé.
    Si on exclut la question de la performance, l'absence à l'accès au code de l'implémentation est plus problématique à mes yeux. Avec les libraires, cela peut devenir vraiment un problème.

    Je ne sais pas si tu te souviens de la sonde spatiale qui s'était écrasé sur Mars pour un problème de calcul de conversion de mesures impériales à métrique. La formule de calcul était exacte, mais les marges d'erreurs était insignifiantes pour des calculs sur la Terre. Mais devenait problématique lorsque cela impliquait des distances interplanétaires.

    Si les ingénieurs avaient eu accès à la formule utilisé par la fonction de conversion, le désastre aurait été évité.

    (Depuis la NASA ne fonctionne plus qu'avec le métrique)

    Citation Envoyé par Pyramidev Voir le message

    Citation Envoyé par Madmac Voir le message
    Ayant débuté la programmation-object sur Pascal, j'ai toujours trouvé bizarre cette fabrication systématique d'accesseurs. Je crois que cette pratique est ce qui pénalise le plus la performance des programmes en C++ (en excluant l'héritage)
    Non. En C++, si tu écris un accesseur très basique ou un mutateur très basique directement dans le ".h", il n'y aura pas de baisse de performance en mode release, car le compilateur va optimiser en remplaçant l'appel de la fonction par le code de cette dernière (c'est l'inlining). Pour l'héritage, ça dépend des cas. Par exemple, le CRTP n'introduit pas de pointeur vers une table virtuelle dans la classe dérivée.
    Ce que je voulais dire qu'en Object-Pascal, une variable de classe est également deux fonctions (getter et setter). Donc, le programmeur n'a à en créer. La fonction optimisée est utilisé par défaut. Le programmeur n'écrit un setteur que lorsqu'il désire faire une vérification (taille ou limite par exemple). Donc par défaut c'est un accès direct ou par une fonction sans que l'on ait à modifier le code. Donc Coord.x est valide peut importe le type d'un accesseur.

    Autre différence de philosophie. le programmeur peut dicter le type de pointeur sur la fonction. Par défaut, les pointeurs sur les méthodes sont des smart pointers. La directive static transforme une méthode en une fonction amie, sans que l'on ait à faire une déclaration à l'extérieur de l'objet.

  5. #5
    Membre régulier
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Août 2018
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur validation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2018
    Messages : 37
    Points : 123
    Points
    123
    Par défaut
    Je ne connaissais pas cette sonde, mais ça me fait penser au fiasco du vol inaugural d'Ariane 5.
    Dans les deux cas, je ne vois cependant pas les détails techniques du langage comme cause première de l'incident.

    Ces logiciels n'ont pas été correctement testés.

    Une fonction, une classe ou une bibliothèque proposent un contrat au code qui les utilise. Ce code appelant doit s'engager à fournir des paramètres corrects, le code appelé doit s'engager à donner les résultats attendus.
    La façon précise dont ce code réalise sa part du contrat ne regarde pas le code appelant.

    En pratique, le souci est de s'assurer que le contrat est suffisamment clair et complet. Et la syntaxe du C++ (et sans doute de la plupart des langages) ne suffit pas pour exprimer complètement un contrat, en particulier pour les problèmes d'arrondis dans les calculs de nombres flottants.
    Les procédures de tests d'intégration et de validation doivent permettre de s'assurer que les deux parties ont bien compris les termes du contrat de la même façon.

    Encore faut-il avoir des spécifications précises, un client qui sait ce qu'il veut, des développeurs qui connaissent les limites de leurs outils... bref, toutes ces petites joyeusetés qui font que l'informatique est une discipline encore immature.

  6. #6
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par Grool Voir le message
    Je ne connaissais pas cette sonde, mais ça me fait penser au fiasco du vol inaugural d'Ariane 5.
    Dans les deux cas, je ne vois cependant pas les détails techniques du langage comme cause première de l'incident.
    Dans le cas d'Ariane 5, les ingénieurs ont utilisés le code utilisé pour un autre lanceur sans faire des ajustements, car les deux lanceurs étaient de tailles différentes.

    Dans le cas de la sonde qui s'est écrasé sur Mars. Le problème n'est pas tant le langage, que la formule de conversion était à l'intérieur d'une fonction privée. Ce qui représente deux gros problèmes:

    - Il est impossible de vérifier une fonction privée directement.
    - Il est impossible de modifier ou de surcharger cette fonction.

    Forcément, puisque les programmeurs qui utilisent cette bibliothèque n'ont pas accès au nom de la fonction privée. Il y a peut-être des versions qui le permettent. Mais en général,ce n'est pas le cas.

Discussions similaires

  1. Réponses: 28
    Dernier message: 27/03/2019, 16h58
  2. Réponses: 11
    Dernier message: 04/03/2014, 10h54
  3. Réponses: 0
    Dernier message: 12/03/2012, 13h45
  4. [Article] Tout ce que vous devez savoir sur la déclaration !important
    Par 12monkeys dans le forum Publications (X)HTML et CSS
    Réponses: 0
    Dernier message: 16/08/2010, 21h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo