Citation:
Envoyé par
Mac LAK
Et alors ? Si c'est en lecture seule, ça n'a aucune importance, sauf celui de te permettre d'avoir du code d'introspection.
Si c'est en écriture, tu as des tonnes de mécanismes permettant de blinder cet aspect (sections critiques, enregistrement via par exemple le TLS, encapsulation et/ou private implementation, singletons, pointeurs avec compteur de référence, et j'en passe).
C'est justement là le problème...
Je suis bien d'accord qu'un acces en lecture ne pose-- de manière très théorique du moins, à condition de faire l'impasse sur les accès concurrent -- à peu près jamais de problème.
Par contre, un acces en écriture se doit d'être aussi encadré que possible et d'être permis de manière aussi restreinte que possible
Comme les propriétés, même si elles permettent le choix de l'acces qu'elles autorisent, sont, par défaut, d'accès "global" (comprend: accesssible depuis n'importe quel endroit du code, même s'il y a des conditions à remplir), tu permet à tout le code d'avoir un acces en écriture sur des objets au sujet desquels un tel acces devrait être particulièrement restreint.
Je suis, encore une fois, désolé d'insister sur ce point, mais c'est loin d'amener une situation idéale ;)
Citation:
Rien ne t'oblige à publier 100% de tes attributs dans des propriétés RW, ni à remplacer le concept d'attribut par celui de propriété.
Une propriété est une interface de la classe : si quelque chose ne doit pas être manipulé de l'extérieur, pourquoi diable voudrais-tu en faire une propriété ???
Le problème, c'est, encore une fois, que, à faciliter la mise en oeuvre de chose dont l'usage devrait à chaque fois être décidé après mure réflexion, tu n'incite les gens à créer des propriétés "par habitude", y compris pour des attributs qui n'ont nul besoin d'être représenté sous cette forme, et, pire encore, tu encourage le développeur (vu que c'est l'une des possibilités de la propriété) à fournir un acces en écriture à un attribut qui, non seulement, ne devrait déjà pas être accessible en lecture "depuis l'extérieur", mais au sujet duquel il est encore plus incohérent d'envisager d'en permettre un acces en écriture.
Bien sur, tu me dira qu'il faut laisser les "bons" programmeurs faire le boulot, mais je te rappelle encore une fois que tous ne sont pas aussi bons qu'ils ne peuvent le laisser croire...
Citation:
Pas plus qu'un accesseur... C'est très exactement la même chose, seul l'utilisateur voit une différence réelle entre les deux.
Ca facilite grandement, au contraire, vu, qu'à l'extrême limite, il suffit d'une ligne de code pour... exposer aussi bien le mutateur que l'accesseur...
Citation:
Avec une propriété, si... ;) Du moins, c'est l'impression qu'aura l'utilisateur.
Et c'est presque plus un risque qu'un avantage...
Tu le sais aussi bien que moi, l'homme est par nature un imbécile distrait.
Le programmeur n'étant qu'un homme, il est, lui aussi, un imbécile distrait (et je me mets volontiers en tête de liste ;))
Et tu connais surement tout aussi bien la loi de murphy, qui dit que, s'il est possible de faire une connerie, tu trouvera toujours quelqu'un pour la faire.
Au final, si tu donnes la possibilité à quelqu'un de modifier un attribut alors qu'il ne le devrais pas, tu dois t'attendre à rencontrer "un imbécile" pour essayer de le faire.
Bref, avec les propriétés, tu as beaucoup trop tendance à centraliser des comportements qui feraient beaucoup mieux... de rester clairement séparés.
Citation:
Tu me reparles de multiples fonctions de redimensionnement, moi je te parle d'un concept unique de taille (ou capacité, si tu préfères). Cela n'empêche absolument pas d'utiliser une méthode Add() pour ajouter un élément, wrappant au besoin un sous-container. Quand aux fonctions de modification de taille, il est souhaitable qu'elles existent de façon unitaire (erase(), resize(), incsize(), decsize(), que sais-je encore...) et qu'elles soient utilisées au sein de l'interface "Write" de la propriété, en fonction de la valeur passée en paramètre.
Oui, si tu y tiens, rajoutons incsize et decsize... bien que je ne les ferais pas apparaitre dans l'interface publique (ne serait-ce que pour des problèmes d'initialisation de l'élément ajouté par incsize :P)
Citation:
Bref, c'est à toi de t'assurer que tu respectes ton contrat, c'est à dire que ta taille a été augmentée d'une unité après un ajout... Le formalisme utilisé (méthodes ou propriété) n'a absolument aucune importance, sauf pour l'utilisateur final qui y gagne en simplicité.
En simplicité et en capacité de faire des conneries, parfois même sans s'en rendre compte, parce qu'un caractère "malencontreux" peut te faire passer en "ecriture"...
Un bête exemple, si l'auteur du code oublie le deuxième = lorsqu'il utilise la propriété "size" à l'intérieur d'un test, il aura modifié la taille de la collection, sans s'en apercevoir, et avec des conséquences pouvant être catastrophiques
Citation:
Je trouve plus confusant d'avoir N points d'accès à un concept donné (ex : la capacité d'un container) au lieu d'un seul et unique, dont la valeur ou le cadre d'utilisation (L/R-Value) est proche de la représentation "humaine" dudit concept. Une taille/capacité se lit, se détermine, peut augmenter, diminuer, être réduite à néant. C'est une formalisation assez proche de ce que l'on trouve fréquemment dans les spécifications de besoin, en fait.
Il n'y a rien de confus, et il n'y a même pas plusieurs point d'acces à un concept unique:
Tu as, sans doute, un attribut qui garde en mémoire le nombre d'éléments que ta collection comporte, et tu as:
- une (série de) fonction(s) dont le comportement est clairement déterminé susceptible(s) de modifier cet attribut
- un seule et unique fonction te permettant de récupérer le nombre d'éléments contenu
Citation:
Blague à part : taper dans une map de la STL se fait également via [], simplement tu n'as pas toute la finesse de contrôle qui est possible via find/insert. Et alors ? Les exceptions existent pour ça, ce sont effectivement des comportements non-nominaux de tenter de récupérer un élément inexistant et/ou d'écraser un existant, mais ça peut parfaitement convenir à la plupart des besoins.
Pourquoi s'emm.... avec un itérateur et des méthodes find/insert, alors que l'on contrôle en amont ce qui est lu/écrit dans la map, et que les exceptions (cas anormal et rarissime) conviennent parfaitement à la gestion des erreurs ? L'opérateur [] fait parfaitement l'affaire, est cent fois plus simple à utiliser, et répond au besoin. Utiliser autre chose, c'est simplement aimer se compliquer la vie pour rien.
A vrai dire, je fais partie de ceux qui regrettent profondément la présence de [] dans les std::map et qui regrettent encore plus profondément le fait que la sémantique qui est donné à cet opérateur permette aussi bien de rechercher un élément que d'en insérer un...
Citation:
Pour toi, peut-être. Pour moi, c'est un index, ni plus, ni moins, avec des limites hautes et basses et (par défaut) pas de "trous" dans son domaine. Son caractère aléatoire et/ou direct m'importe peu.
Peut être n'est ce que pour moi, mais, même si ce n'est que du à la force de l'habitude du C, j'estime que, bien que le fait qu'il permette d'avoir des limites hautes et basses, sa principale qualité tient, justement, dans le type d'acces aux différents éléments...
Citation:
Je le vois comme "méthode pratique et basique d'accès", ni plus, ni moins. Je ne pars pas du principe que c'est l'accès le plus performant (même si c'est souvent le cas), je pars du principe que c'est le plus PRATIQUE. C'est très différent.
Partique, peut être, mais, encore une fois, à quel prix :question:
Citation:
Heu... On ne doit pas avoir le même sens pour sémantique (="le fond"), que j'associe en général au mot "syntaxe" (="la forme").
La sémantique, c'est l'opération à effectuer (récupérer un élément, avoir la taille du container, etc.). La syntaxe, c'est la forme que cela prends (propriété, méthode, accesseur, service réseau, glutz vénusien...).
La sémantique, c'est le sens que l'on donne (de manière conventionnelle ou consensuelle) à un terme.
C'est ce qui te permet de ne pas recevoir un couteau ou une fourchette lorsque tu demande une cuiller.
Si un terme a un double (ou pire, un triple/quadruple/... sens), il ne faut pas t'étonner si, à un moment donné, les gens se trompent sur le sens qu'il fallait donné à ce terme, c'est aussi simple que cela...
Encore une fois, en centralisant plusieurs comportements fondamentalement différents en un seul terme, tu augmente le risque de voir apparaitre des contre sens ou des erreurs dues, essentiellement... à la mauvaise évaluation du sens à donner à ce terme dans une situation donnée
Citation:
Encore heureux que les fonctions s'adaptent aux circonstances : comment voudrais-tu faire de la gestion d'erreurs sans ça ???
Sans même parler des surcharges de méthodes...
Je pense que tu as voulu dire autre chose que ce que je suis en train de lire : peux-tu reformuler, stp ?
Elles s'adaptent au circonstances, mais gardent des comportement dont le but estfondamentalement identique...
Il est bien évident que, dés que tu as un test ou une boucle, ta fonction s'adapte aux circonstances, mais le but recherché par ta fonction est... fondamentalement unique
L'adaptation aux circonstances que tu permet au travers de propriétés (RW, je l'accorde), c'est d'avoir des comportements fondamentalement différents, et c'est là que repose le problème
Citation:
Ce qui est le cas d'une propriété, clairement définie comme telle bien entendu, qui regroupe via un seul identifiant un concept complet telle que la taille / capacité d'un container, au lieu de disperser cette information sur N entités diverses.
Donc, un seul point à documenter / assimiler, et tu as l'accès à toutes les fonctions liées à un concept. Difficile de faire plus simple, plus concis et plus compréhensible, je trouve.
Au niveau de la documentation à fournir, tu ne gagne pas grand chose à utiliser les propriétés, ne serait-ce que du seul fait que, si elles présentent deux comportement, tu devra quand meme documenter les deux comportements mis en oeuvre, et tu devra, en plus, indiquer dans quel cas tel ou tel comportement sera mis en oeuvre.
Du point de vue de l'utilisation, je préfère avoir trois fonctions clairement distinctes pour lesquelles une simple phrase commençant par "cette fonction fait..." que d'avoir un "concept" (quelque part fort élargi :P) et devoir me rappeler de... tous les cas d'utilisation (si je fais ceci, j'aurai tel résultat, mais si je fais cela, j'aurai tel autre résultat, et, si d'aventure, j'ai une troisième possibilité, j'aurai encore quelque chose d'autre)
Sans oublier, en plus que le simple fait d'écrire = au lieu de == risque de provoquer des catastrophes.
Ca fait cher payé pour un caractère oublié, non :question:
Citation:
Des concepts comme les propriétés permettent de rendre les classes plus "intelligentes", sans pour autant complexifier leur interface publique, ni les rendre spécialement moins performantes, ni spécialement plus longues à écrire. Pour ma part, je trouve que ça va dans le bon sens, étant donné que développeur comme utilisateur y gagnent.
Cela ne rend, effectivement, pas l'interface plus complexe, mais, encore une fois,à quel prix :question:
- Cela rend plus complexe le fait de déterminer exactement le comportement que l'on met en oeuvre en fonction du "contexte"
- Cela risque d'entrainer des catastrophes si, d'aventure, on utilise le "mauvais contexte"
- Cela ne rend pas forcément la lecture et la compréhension plus facile
Je suis désolé, mais c'est un prix que je ne suis pas près à payer si je peux l'éviter...
Citation:
Bon, désolé du pavé, mais t'es au moins "aussi pire" que moi au niveau longueur des posts... ;)
Ne t'en fais pas pour ca... je suis connu pour la longueur de mes posts :D