Maurice, pousse-je le bouchon trop loin ?
(C'est pénible ce "quote" qui enlève les "quote" de niveau supérieur...)
Citation:
Envoyé par
Mac LAK
Même pas : le "re" sous-entends que l'opération est une modification à chaud, et non pas une primo-allocation. Pour faire plus clair, c'est comme si tu me disais que tu utilises realloc à la place de malloc de façon constante. Le nom serait exact si c'était "setsize", et non pas "resize"... Et une documentation est nécessaire pour savoir si les éléments sont conservés ou pas : on va donc l'appeler "setsizewithelementconservationexceptifsizeisreduced"... Ouais, super.
Là, j'en suis sûr, c'est de la mauvaise foi :)
Citation:
Envoyé par
Mac LAK
Si c'est la même chose, en quoi le définir en accès unique est-il un problème ? ;)
J'ai pas eu le sentiment d'écrire que c'était la même chose. Je pensais même essayer de démontrer que non, ce n'est pas la même chose, et que l'utilisation de fonctions pour effectuer des actions a plus de sens que l'utlisation de propriétés.
Citation:
Envoyé par
Mac LAK
Avoir l'équivalent, en terme d'unicité d'accès, sans utiliser de propriétés revient à déclarer une sous-classe très fortement imbriquée dans sa classe parent, contrôlant justement tous les aspects liés à la taille.
Là je dois être un poil idiot, mais je ne vois pas ou tu veux en venir.
Citation:
Envoyé par
Mac LAK
C'est plus simple dans le sens où tu n'as qu'un seul accès pour un concept donné, donc inutile de chercher à côté s'il existe autre chose : tout est là.
Je ne vois pas en quoi écrire "myClass.Size = 20 ;" est difficile à comprendre d'un point de vue syntaxique, ou même sémantique... La taille du machin est mise à 20, point, c'est simple et net.
Simple ? Net ? Ah bon.
Quelques questions :
1) est-ce qu'une action particulière est effectuée ? Parce que ça ne me dit pas qu'une action particulière est effectuée, si ce n'est l'affectation.
2) Est-ce que Size est une propriété ou une variable dont on a laissé imprudemment (ou au contraire avec beaucoup de sagesse peut-être) l'accès à tous ?
3) ce code peut-il renvoyer un code d'erreur ? Parce que si ça se trouve, je ne peux pas me permettre de traiter des exceptions dans la section de code qui l'utilise.
Maintenant, je repose les même questions avec une fonction resize().
1) ben à priori, une fonction particulière est effectuée. C'est dit dans le nom de la fonction.
2) Euh, c'est une fonction. Publique.
3) si ma fonction resize() échoue, on peut imaginer qu'un code d'erreur va être retourné (évidemment, je ne parle pas des fonctions équivalentes de la C++SL). Je n'ai pas besoin de traiter une exception.
Que d'avantages !
Citation:
Envoyé par
Mac LAK
Pour le développeur ? Bien entendu... La philo Unix est même basée sur un principe similaire, d'ailleurs. Mais pour l'utilisateur, par contre, non : c'est au contraire quelque chose de crucial.
Euh... non. La philosophie (des utilitaire) d'Unix n'est basé sur rien de concret. C'est même une horreur tellement il n'y a rien derrière.
Citation:
Envoyé par
Mac LAK
Si tu veux une analogie, c'est la différence entre une aide façon Windows (avec index, recherche, etc.) et une aide façon manpage. Dans le premier cas, tu peux chercher en fonction du but désiré. Dans le second, il vaut mieux connaître le nom de la fonction pour en avoir l'aide.
(Ou connaitre les options en ligne de commande de man ; mais ce n'est pas le débat).
Tiens, soyons fous et caricatural : imaginons que j'ai une base de donnée accessible via une interface I. Je veux rajouter une fonctionnalité de recherche. Quelle est la meilleure manière de faire :
- ajouter une fonction recherche, qui prends en paramètre une expression de recherche et qui renvoie une liste de résultats trouvés ?
- ajouter deux propriétés
- ExpressionRecherche
- ResultatRecherche
Et expliquer à mes bagnards que changer la valeur de ExpressionRecherche a une influence directe sur le contenu de ResultatRecherche ?
J'ai dans ma petite idée que je saurais quelle méthode choisir, et dans la petite idée que tu va essayer de me démontrer que ta méthode serait mieux.
Citation:
Envoyé par
Mac LAK
Pour ma part, j'ai les deux casquettes à la fois : je développe des API pour les autres, et j'en utilise moi-même (y compris les miennes, bien sûr). Je sais aussi que ça vaut le coup de passer 5% de temps de plus sur le dév, pour faire de "l'inutile" fonctionnel, mais qui me permettra d'avoir une paix royale par la suite sur l'utilisation.
Je fais ça aussi. Je sais par expérience que créer une interface simple est une tâche très compliquée. Ce n'est pas pour autant que je vais faire des compromis avec ce que je pense être une opinion argumentée et logique. Ajouter une fonction au nom évocateur n'est pas plus compliqué que d'ajouter une propriété.
Citation:
Envoyé par
Mac LAK
Côté code interne à la classe ?? Mais quel besoin as-tu d'y mettre les mains pour l'utiliser, de façon générale ??
Ou est-ce que j'ai parlé de code interne ?
Citation:
Envoyé par
Mac LAK
Quant aux données intrinsèques... C'est impossible d'avoir, de façon constante et systématique, l'absence totale de publication d'éléments intrinsèques. La taille d'un container devra forcément être publiée d'une façon ou d'une autre, un itérateur est une manière également de parcourir la structure interne d'une classe, etc. Si l'on raisonne sur le FOND et non pas sur la FORME, l'exposition de données intrinsèques est obligatoire.
Et bien, heu, non. Je n'aurais pas de fichier de configuration sur mon projet, je n'aurais exposé aucune donnée intrinsèque. Et si je l'ai fait, c'est uniquement parce que j'ai jugé, dans un moment de faiblesse, que c'est suffisamment idiomatique pour être pardonnable.
Citation:
Envoyé par
Mac LAK
Pour le reste, j'ai plus de facilité à suivre les données que les actions, au contraire. Heureusement, la plupart des informaticiens sont à peu près bons en maths.
Si tu veux dire par là qu'une bonne majorité est capable ne pas se mélanger les pédales entre addition et multiplication, je suis d'accord avec toi. Si tu prétends qu'une bonne partie maitrise les notions exposées par Galois dans ses Anales de Mathématiques Pures et Appliquées, j'ai un léger doute. Mais tu as peut-être raison.
Citation:
Envoyé par
Mac LAK
Pour les non-informaticiens, j'ai souvent moins de mal à leur représenter les concepts inclus dans une classe sous forme d'entité pouvant être manipulée que sous forme d'actions élémentaires incluses dans la classe parent.
Oui, ça mérite même un billet de ma part. Si je présente à un individu lambda un design ontologique, il aura beaucoup de facilité à le comprendre. Si j'essaie de transformer ce design en code, je vais droit dans le mur - parce que l'approche ontologique est nécessairement limitée. Le même problème se pose dans d'autres domaines liés au code. "goto" est plus compréhensible que l'appel de fonctions - ça ne veux pas dire que c'est mieux. Le code de liste chainée pondue par un étudiant en 1ère année d'info sera simple à comprendre, ça ne veut pas dire que sa liste chainée aura les même qualités que celle présente dans la C++SL.
Encore une fois, il s'agit de passer outre la dualité simplicité/simplisme, pas de l'exploiter. De manière générale, les architecture qu'on prétend "idiot-proof" sont aussi "user-proof" à long terme.
Citation:
Envoyé par
Mac LAK
Heu... Ne me dis pas que tu ne distingues pas une L-Value d'une R-Value, quand même.
Bon, je me suis mal exprimé (argh). Une propriété, à moins que je ne me trompe, n'est ni une R-value, ni une L-value. C'est une propriété. L'accès en lecture et l'accès en écriture ne ressemble en rien à l'utilisation d'une L-value. Le fonctionnement de ces deux accès peut être extrêmement différent.
Citation:
Envoyé par
Mac LAK
Ce n'est pas la même chose de lire et écrire une entité, même si ce sont bien entendu des opérations complémentaires. Je ne vois pas en quoi son rôle n'est pas unique...
Que dit-on d'une chose qui a deux fonctions différentes ? Combien de rôles a-t-elle ?
Citation:
Envoyé par
Mac LAK
Tout comme une fonctionnalité peut être effectuée de plusieurs manières différentes sur les containers STL, par exemple : tu peux faire un erase() ou un resize(0), c'est pareil : où est l'unicité de la fonction, dans ce cas ??
resize(0) redimensionne le tableau pour qu'il contienne 0 élément. erase(begin(), end()) efface les éléments qui sont situés entre begin() et end(). clear() supprime tous les éléments du tableau. Le résultat de ces actions est le même, ce qui ne veut pas dire que ces fonctions ont plusieurs rôles. Ce sont deux notions indépendantes.
Citation:
Envoyé par
Mac LAK
Ou le contraire : ça t'évite d'avoir plusieurs noms redondants pour décrire un concept unique. A condition d'arrêter de voir une propriété comme un attribut bête et méchant, et de la prendre en tant que concept, bien sûr.
Une propriété n'est PAS un attribut, même si elle s'utilise de la même manière. Ce serait aussi idiot que de dire qu'une fonction C et une fonction macro (préprocesseur) sont la même chose, juste parce qu'elles ont des parenthèses et des paramètres.
Je suis entièrement d'accord sur ce point. Chaque outil a une fonction (tiens, comme c'est étrange :) ).
Citation:
Envoyé par
Mac LAK
Certes. Derrière, par contre, tu oublies que l'on a aussi des contraintes budgétaires, calendaires,techniques et humaines. OK, c'est idéaliste, mais c'est justement pour ça que ce n'est pas applicable. En pratique, ce n'est d'ailleurs pas de l'idéalisme, mais de l'utopie.
Je ne dirais pas le contraire. Mais en même temps, mon rôle en tant qu'architecte logiciel n'est pas juste de trouver des solutions à un problème mais trouver des solutions optimales au vu des contraintes (budgétaires, techniques...) qui s'appliquent à ce problème particulier. Et dans mon métier, taper dans l'idéalisme permet de développer des idées qui vont dans le bon sens. Développer des concepts, réfléchir sur le sens des outils qui sont à notre disposition, transmettre mes connaissances dans ce domaine particulier, tout cela fait partie de mes attributions.
Citation:
Envoyé par
Mac LAK
Justement, tu as dis le mot : "simples"... Réussir à transformer une problématique complexe en un programme performant, on sait tous que c'est tout sauf trivial (et ceci que l'on soit collé au matériel ou dans les domaines de très haut niveau, d'ailleurs).
Le plus souvent, on arrive à un résultat performant, certes, mais difficile d'utilisation. Quel est le besoin qui pousse la plupart des dévs à se contenter de ceci, au lieu de simplifier les interfaces pour l'utilisateur et donc de "simplifier" le problème général pour celui qui utilise la boîte noire ?
Quand je dis simple, je fais référence à des problèmes qui sont effectivement simples pour moi (et pour bien d'autres), parce que j'ai déjà passé pas mal de temps à cogiter sur le sujet. Ca ne veux pas forcément dire que ce sont des problèmes simples. Un exemple parmi d'autres : stockés sur mon disque dur, une librairie qui encapsule l'aspect GUI de Windows, tout en restant simple d'utilisation. Ou l'encapsulation d'API 3D (DX + OpenGL). Ce sont des problèmes que je considère comme simple maintenant, parce que j'ai passé des mois - voire pour certains des années à affiner les concepts sous-jacents de manière à avoir une code très light, performant, et simple comme bonjour à utiliser. Ce sont des projets de type test-bed, et j'utilise les connaissances acquises pendant leur développement pour avancer dans mes capacité de modélisation objet.
Un problème simple est un problème qui admet une solution simple et élégante. Ca ne veut pas dire qu'il est résolu simplement - ça, c'est un problème trivial.
Citation:
Envoyé par
Mac LAK
Tout dépend de ce que tu appelles "taille mirobolante".
Pour l'instant, environ 20,000 lignes de code (hors lignes blanches et lignes de commentaire ; parce que doxygen, ça prends une place folle dans un fichier...). Ca reste quand même très modeste. En même temps, si le client me donne 3 ans pour faire un projet, il sera nécessairement plus gros - mais ça ne veux pas dire que je vais sacrifier ma façon de faire sur l'autel de la pseudo-simplification.
Citation:
Envoyé par
Mac LAK
Pour ma part, on est une vingtaine en permanence sur le projet, qui dure depuis presque 10 ans, et avec un turn-over énorme. Crois-moi, dans ce genre de cas, tu cherches au maximum à simplifier les interfaces d'utilisation, quitte à rendre le code interne (mais normalement caché) un peu plus difficile d'accès. De toutes façons, il est nettement plus souvent utilisé que modifié, donc ça convient très bien de privilégier l'utilisation à la modification.
Je ne vais pas critiquer ça. Je critique le fait d'utiliser des propriétés, qui selon moi (et ça n'engage que moi) ne simplifie en rien le code client.
Citation:
Envoyé par
Mac LAK
D'un point de vue "conception interne de la classe et méthodes à développer", les propriétés ne simplifient RIEN. Par contre, elles simplifient l'utilisation de la classe, en centralisant les points d'accès et en simplifiant les appels. Ce n'est que de la syntaxe, la sémantique est très exactement la même que les accesseurs, mutateurs ou attributs suivant ce que l'on décide de mettre en propriété. Cela ne t'empêche pas de faire ce que tu veux (elles n'ont rien d'obligatoire), et permet de méchamment simplifier des interfaces qui pourraient devenir franchement infectes. Bref, où est le problème ??
Le problème c'est que, perdu que tu est dans ta défense des propriétés, tu ne vois pas le problème. Tu le dis toi même, la sémantique des accesseurs/mutateurs et celle des propriétés sont quasi-identique. Un peu d'historique ici ou de lecture de mon blog montre que je n'aime pas non plus les accesseurs. J'ai, je pense, des bonnes raisons de ne pas les aimer.
Citation:
Envoyé par
Mac LAK
Là, j'ai l'impression de voir un remake du bon vieux troll "caster le malloc en C" : on hurle sur quelque chose qui ne gêne que les puristes, simplifie la vie des utilisateurs (et je rappelle que l'on code pour que ce soit utilisé, hein, pas pour mettre en vitrine), et pour lesquels les "désavantages" sont des problèmes largement plus issus de la conception que de l'implémentation...
Ben justement, mon métier à moi c'est plus la conception que l'implémentation. L'implémentation vient en second, et elle est relativement simple si la conception est solide. De même, toujours si la conception est solide, le résultat sera non seulement simple d'utilisation mais aussi logique et (j'y reviens) expressif. Mon idéal est une librairie dont l'utilisation ne nécessite pas de commentaires dans le code client. Son interface doit être complètement explicite. Si son utilisation implique des cas d'erreur, elle doit faire en sorte que le maximum soit détectée au moment de la compilation.
J'obtiens des résultats que je juge substantiellement de meilleure qualité que le code que j'ai l'habitude de voir ici et là. Et, par un hasard que je ne saurais expliquer, mes clients disent la même chose. Mes clients se foutent des choix technico-philosophiques que je fais. Ca ne m'empêche pas de les faire, parce que ce faisant, je me simplifie le travail et je simplifie la tâche de ceux qui vont utiliser mon travail.
Alors non, on ne débat pas de choses qui n'intéresse que les puristes. On débat de choses qui intéressent tout le monde parce qu'elles touchent aux notions les plus profondes de l'architecture et la programmation professionnelle, mais le message se perd aisément, noyé qu'il est sous les remous provoqués par ceux qui ne perçoivent pas les raisons sous-jacente à ce débat. Au final, oui, ça devient un combat de puriste, parce qu'il faut sans cesse aller expliquer le moindre petit mot utilisé, la moindre formulation, la moindre base d'idée, et sans cesse relier le sujet à d'autres qui n'ont pourtant que peu de relations avec lui, tout ça pour n'arriver à rien - parce que ceux que ça pourrait intéressé ne peuvent plus suivre la conversation, et ceux que ça n'intéresse pas du tout veulent absolument la continuer, histoire de prouver que leur manière de faire est suffisamment bonne.
Si vous jugez votre manière de faire suffisamment bonne, continuez à faire comme vous le souhaitez.
Si vous souhaitez améliorer vos pratiques mais que pour une raison X ou Y vous ne le pouvez pas, ça ne vous empêche pas de garder au fond de votre esprit que les propriétés telles que C# (par exemple) les présente sont une fausse bonne idée. Quoi qu'en disent ceux qui les utilisent.
Et maintenant, il y a Dr House, donc je suis pris :)