tss tss... Et là j'aurais encore l'argument de l'encapsulation...
Mais même ce code je ne le présuppose pas comme vrai :
Pour moi cette assertion peut claquer. (bon sur un int j'exagère un peu, bien que ça dépende du contexte).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 int var(0); //... var = 4; assert(var == 4);
Les contrats implicites c'est bon pour se prendre des baffes dans la figure.
Ah mais si tu explicites tous tes contrats, on va être copains . Le fait est que dans la vie réelle, on est déjà content quand on a de vagues infos sur les préconditions, alors les postconditions…
Mais aller contre les postconditions ou la sémantique « intuitives », « implicites », n’apportera que des problèmes. Tu peux le reprocher à l’utilisateur de ta classe, tu peux aussi faire en sorte qu’il n’ait pas de mauvaises intuitions. Le deuxième me semble plus productif .
c'est pas pour jouer les chieurs, mais lire le contrat pour les getters/setters est tout aussi important que pour les autres fonctions, ici on a un bon exemple, length pour une chaine de caractère, ça renvoit quoi? le nombre de caractère ou la taille de l'espace mémoire pour stocker cette chaine?
si la chaine est en utf8 par exemple, les caractères pouvant être stockés sur plusieurs octets, les 2 possibilités peuvent varier du simple au triple.
je serai de l'avis de germinolegrand, éviter les présomptions, même sur ce qui pourrait être une évidence.
Le problème, c'est que tu as beaucoup plus de contrats implicites que de contrats explicite.
Pour avoir des contrats explicites, il faut soit un cartouche au dessus de la fonction qui rend les contrats explicites (RTFM ), soit que la fonction soit correctement nommée; l'idéal étant bien sur d'avoir les deux
Et quand tu te trouves avec une fonction setXXX qui fait plus que ce qu'elle ne dit (définir la valeur de XXX à celle que tu indique) ou pire, qui ne le fait pas du tout (parce qu'elle divise la valeur indiquée par deux ou que sais-je), on ne peut déjà pas se baser sur le nom de la fonction.
Et comme un mutateur disposera rarement d'un cartouche ("c'est une fonction si simple, je vais pas perdre cinq minutes à écrire un commentaire pour cela" t'objecteront certains )... il devient difficile d'avoir un contrat explicite
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Encore faut il que le contrat soit explicité
Avec une fonction setXXX, le seul moyen, c'est de se raccrocher au bon vieux RTFM.
Le problème, c'est que certains (beaucoup ):
- ne mettront jamais un commentaire, meme en cartouche ("un commentaire non mis à jour est pire que pas de commentaire du tout" t'objecteront ils)
- ne "perdront quand meme pas de temps à écrire un cartouche pour une fonction si simple que setXXX"
- trouveront surement d'autres raisons pour ne pas expliciter le contrat
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
je suis d'accord, mais mettre "tout" à la poubelle à cause des mauvaises pratiques des dév, même si c'est la majorité, ça me reste en travers de la gorge
Non, c'est un comportement ou un service attendu / rendu par ton objet
J'ose en effet espérer que tu ne placeras un mutateur que lorsque tu as effectivement besoin de pouvoir faire varier une donnée parce que cela correspond à un comportement ou à un service attendu de la part de ton objet
L'opérateur = n'est utilisable que lorsque tu veux assigner une valeur à une variable existante!Sinon, on n'a pas besoin de mutateur : on met un opérateur =.
Mais si tu veux assigner une valeur à un membre de ton objet, tu ne peux pas utiliser l'opérateur =.
Tu imagines un peu le code
Ca ferait du dégât dans les chaumières, non
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Button button(/* paramètres */); Font uneFont(/* paramètres*/); obj = uneFont;
Mais setY ne modélise pas une fonction mathématique, elle modélise un comportementSi tu as une fonction setY() qui modélise une fonction mathématique, tu ne t'attends pas à ce que setY(5) induise que Y = 5.
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Il y a clairement deux visions différentes ici :
- ceux qui pensent que l’utilisateur n’a qu’à lire la doc (le cartouche de la fonction).
- ceux qui pensent que l’utilisateur ne lit pas la doc, et que pour cette raison le code doit être le plus explicite possible, ce dès le nom de la fonction.
Mon expérience personnelle est que, quand on lit du code (en particulier quand on arrive sur un code qu’on ne connaît pas), on ne commence pas par lire pas la description de chaque fonction (beaucoup trop long), on présume de ce qu’elle fait en fonction du nom.
Mon autre expérience personnelle est que l’utilisateur lui-même ne lit pas la doc, et ne va pas se méfier des effets de bord. Que rien que lui faire lire un contrat du type « non, ma fonction n’accepte pas un pointeur null comme paramètre » est déjà difficile. Alors espérer qu’il se préoccupe d’effets de bord, de complexité des fonctions, etc, est largement au-delà de toutes mes espérances.
Après, si certains ont des expériences contraires, je serai ravi de les entendre. Mais j’ai du mal à comprendre comment certains peuvent trouver que des get/set non symétriques ce n’est pas un problème, alors que c’est seulement une source d’erreur supplémentaire dont on peut aisément se passer et que fondamentalement ça n’apporte rien comme plus-value.
Le seul contrat que j'offre en post-condition c'est que l'objet soit dans un état cohérent, mais je ne garantie pas plus. Donc pas de problème de contrat implicite
edit : bon sinon j'avoue je suis dans une optique de Read The Fucking Source Code.
oui, mais bon...
C'est une solution qui a tendance à tendre énormément les relations entre collègues.
Et qui, pour être applicable, doit etre appliquée dés le début du projet.
Lorsque tu arrives sur un projet qui est déjà composé de 2500 fichiers, dont certains ont été écrits par des types qui ne font même plus partie de l'équipe, tu as rarement l'autorité nécessaire (je cherche en fait un autre mot sur lequel je ne reviens plus) pour le faire, surtout quand tu débarques sur le projet
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Mon expérience personnelle est que la personne qui crée la fonction n'est pas la plus légitime pour déterminer si son nom est "auto-explicatif".
Il le sera pour cette personne, car elle baigne dans le contexte depuis plusieurs jours. Pour les autres, c'est loin d'être toujours aussi évident.
Ben, il sera beaucoup plus auto-commenté avec un nom qui indique (même de manière partielle) le résultat que l'on obtient qu'avec un simple setXXX
Pour autant que j'aie pu en juger dans les différents codes que j'ai parcourus, ma notion du set semble pourtant relativement partagée...
Mais peut etre pourrais tu exprimer ta notion de set, pour que nous puissions en discuter (et te faire changer de point de vue, qui sait )
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Mouais.
Enfin, les setters c'est généralement une double mauvaise pratique
- mise des données en avant au lieu des services, et autre viol de la loi de Déméter (certes, retour à l'argument GUI vs métier -- mais notre métier est-il d'écrire des GUI ?)
- et nom menteur car il ne correspond pas à ce qu'il se passe réellement
Alors je pose la question: Qui est assez naïf pour croire que le contrat d'une fonction au nom mal choisi sera explicité et juste ? Oui, c'est une troisième bonne pratique que d'expliciter correctement un contrat et de le maintenir à jour, mais c'est moins grave que le viol de la LoD (à mon avis), et plus cher à faire respecter qu'un nom juste.
Il n'y aurait pas comme de la mauvaise foi et un problème de priorités à revoir dans cette discussion ? Tout ça pour défendre une mauvaise pratique sur le principe qu'elle domine les bases de code existant ?
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager