YAGNI
Geoffrey
Membre
Le croco en parle souvent, cet article est pas mal http://martinfowler.com/bliki/Yagni.html
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Je cherchais des références de livres qui parlent de programmation d'un point de vue un peu "philosophique". Cet article semble donner des références --> cool !
J'ai acheté le livre "Refactoring" http://martinfowler.com/books/refactoring.htmlmais en fait je le trouve pas super.
Si vous avez d'autres conseils de lecture (online ou livre)...
Refactoring est un bon bouquin (comme tous les bouquins de Fowler, je dirais), mais il faut du temps pour adapter son esprit à cette discipline. Personnellement, il a dû prendre la poussière sur l'étagère pendant deux ans avant que je ne le redécouvre. Maintenant c'est pour moi un classique.
@Céroce je ne l'ai pas lu en entier mais je trouve qu'il est trop "formel". C'est moins d'un catalogue aride de méthodes (qui sont souvent comme la prose de M. Jourdain) dont j'ai besoin que d'un discours fait avec du recul et qui est inspirant.
Mais bon, je te fais confiance, peut-être qu'avec plus de poussière je le trouverai mieux ;-)
PS : à quelle occasion ouvres-tu le livre ?
Avec l'expérience, on ouvre certes moins le livre, parce qu'on connait les solutions aux problèmes les plus courants.
L'analyse effectuée dans l'article a le mérite de faire ressortir certains coûts qui sont bien résumés par le diagramme situé au milieu de l'article.
Mais cela reste de l'analyse qu'il ne faut pas confondre avec la réalité.
L'analyse doit permettre de prendre du recul sur les erreurs et sur les succès qu'on a connu. C'est une manière de valider ses acquis en en prennant conscience, pas un guide absolu pour le futur.
Si on s'en tient à cette analyse, on a une vision faible car cette approche ne fait que ressortir les coûts, pas les potentiels. D'autre part elle suppose que les features qui sont potentiellement à réaliser sont connues :
le product owner sait et le développeur fait.
Or la réalité nous montre tous les jours que ce que l'on réalise est un mélange de ce qu'on veut faire (l'approche produit) et ce que l'on peut faire (l'approche technique). Les deux approches se nourrissent et doivent être en communication. Il faut que chacun trouve des idées dans le discours de l'autre or, avec le développement Agile, on a tendance à mettre l'approche produit en amont.
Entre deux designs, il ne faut pas nécessairement choisir le moins coûteux. Et, avant de parler de choix, il ne faut pas s'interdire d'envisager un autre design que le plus évident sous peine de ne pas respecter YAGNI. Notre boulot c'est d'imaginer des solutions, puis de savoir choisir la plus adaptée. Si on respecte trop le YAGNI, on va se censurer dès la phase de création, ou prie dès la phase d'écoute en ignorant totalement le potentiel qu'on peut apporter au produit par le travail d'analyse du métier.
YAGNI est quand même intéressant car il nous faire prendre conscience d'une tendance qu'on peut avoir de partir en roue libre sur la conception, grisé par sa propre capacité d'abstraction, et d'en faire trop en dépit du bon sens. D'ailleurs avant YAGNI, on avait le terme "Usine à gaz" qui jouait le même rôle.
Si vous avez vu le film sur l'histoire d'Alan Turing, The Imitation Game, vous avez un bel exemple du problème que pose YAGNI.
L'exemple de la fin de l'article est amusant. L'auteur dit qu'il utilise les regex pour un algo de highlight d'un texte et développe à partir de là .
Mais, attends un peu, comment en est-il arrivé à utiliser les regex en respectant YAGNI ? >:D
En quoi le respect de YAGNI empêche l'utilisation des regex ?
C'est souvent un peu difficile à maintenir, à debugger et à tester donc c'est typiquement le genre de techno à éviter si on n'en a pas vraiment besoin. C'est puissant mais cela a un coût.
Sauter à la conclusion "RegEx = c'est obscur et compliqué pour moi = c'est pas YAGNI" je ne suis pas entièrement d'accord.
Je vois ce que tu veux dire, mais ça ne me chose pas pour ma part d'utiliser une RegEx même dans le contexte YAGNI.
Par exemple imagine que ton problème c'est de faire une fonction qui valide si un numéro de téléphone est valide, qu'il ait des séparateurs (espaces, ...) entre les chiffres ou pas.
--> Une approche non-YAGNI serait de dire "Ok, faut que je prévois que je vais sans doute avoir à supporter les numéros de téléphones de tous les pays, qui ont divers formats, faut que je me fasse une classe parente PhoneParser, avec des sous-classe (une par format de téléphone connu) ayant une méthode parse(), que je considère que les numéros de téléphones US peuvent être au format court (local) ou long (international), ...
--> Une approche YAGNI c'est dire "ok pour l'instant je cherche que les téléphones français, c'est à dire une chaà®ne qui, quand tu as enlevé les espaces et les points, ne doit plus contenir que exactement 10 chiffres. Bah là , après avoir fait un remplaceOccurrencesOfCharactersInSet pour enlever espaces et point, je fait une RegEx /[0-9]{10}/ et basta.
C'est tout à fait YAGNI car en une seule petite RegEx de rien du tout (ça tient en 9 caractères), il me fait exactement ce que je veux, du moins pour l'usage dont j'ai besoin pour l'instant (<-- = YAGNI) et car c'est une solution simple, du moins dans le sens "j'ai pas pondu une architecture de taré avec des classes "PhoneParser" abstraites parent qui se conforment à un protocole dédié que j'ai fait pour l'occasion et qui ont des sous-classes pour tester les formats possibles et tout. Non, juste une ligne, pas 20 classes et un niveau d'architecture complexe juste pour ça.
Peut-être que demain j'aurais besoin de reconnaà®tre des numéros de téléphone "de n'importe quel pays", et là je n'aurai plus une bête RegEx, mais un truc un peu plus complexe, testant différentes RegEx pour essayer différents formats, me sortir un résultat avec un tableau de probabilité pour tous les résultats possibles et le % de chances que ça colle à un numéro existant au pays, peut-être même que je vais devoir mapper ça à un WebService qui me vérifie si le numéro existe dans ce pays ou pas (genre un numéro qui ressemble au format français car il ferait bien 10 chiffres, mais en fait il commence par "85" et pas "01" à "08")... mais je n'en suis pas là , donc je dis "YAGNI!" et je choisis la solution la plus simple et surtout aussi la plus rapide à implémenter sans me prendre la tête : la RegEx qui tient en 9 pauvres caractères. Car ça me suffit amplement pour l'instant et que j'ai pas à perdre de temps là dessus.
J'ai même envie de dire que n'importe quelle autre solution (où tu aurais fait un NSScanner pour scanner les caractères un à un, ou je ne sais quoi) n'aurait sans doute pas été + YAGNI. Une autre implémentation YAGNI aurait été de compter le nombre de caractères après avoir supprimé les espaces et points, puis si ça vaut 10, faire une itération sur chaque caractère, et vérifier que son code ASCII est entre '0' et '9'... ça aurait été valable aussi, si tu considères ça plus lisible qu'une RegEx de 9 lignes.
l'important dans le YAGNI c'est pas tant "est-ce que ça va être lisible ou pas", ça c'est un autre concept (si t'as peur de pas comprendre ta RegEx plus tard car c'est un peu trop sorcier pour toi, tu peux toujours mettre un commentaire), l'important dans YAGNI c'est de pas perdre de temps à monter une archi complexe et qui anticipe des trucs pour rien alors que tu risques fort d'avoir à la casser quand tu vas finalement avancer dans ton fonctionnel et imaginer de nouveaux usages. Là , si jamais demain t'as besoin d'un fonctionnel plus complexe qui nécessite de détecter des numéros de téléphones de tous pays, tu vas pas te dire, en mettant ta RegEx à la poubelle pour faire un truc plus générique, "pfff perde fait chier j'avais passé 3 jours à faire un code de bourrin pour cette fonctionnalité et faut tout casser", non tu vas te dire "bon c'est pas grave c'était du code fait en 15mn de toutes façon".
La raison c'est que j'ai le préjugé que quelqu'un qui utilise les regex va faire quelque chose de trop compliqué.
J'aurais le même préjugé avec les generics par exemple.
Maintenant je ne suis pas borné et en situation concrete, je peux remettre en cause ce prejugé.
Ton exemple montre une utilisation raisonnable des regex, une utilisation non raisonnable aurait été peut-être de vouloir traiter la chaine avec une regex sans le traitement prealable qui enlève les blancs et les points.
Mais là on est plus dans une discussion sur KISS que sur YAGNI, c'est vrai.
Maintenant, personnellement, dans cas précis, j'aurais fait une boucle pour éviter de charger le moteur de regex. Mais là on entre dans un débat sur les optimisations prematurées.
Sur les regex mon pregujé c'est que cela fait partie des langages rarement rentables en terme de service rendu/cout de maintenace. Comme xslt par exemple. Le probleme c'est que ce sont aussi des langages qui demande une utilisation frequente pour les maitriser.
Tu touches un point essentiel qui n'est pas abordé dans l'article. C'est qu'en tant que développeur, on a toujours du mal à abandonner un code qu'on a écrit. Finalement les cas où on se lance dans une usine à gaz qui aura réellement des conséquences visibles en terme de coût sont rares à l'échelle d'une classe ou d'une fonction.
Le problème c'est plus qu'on sait bien que tout ce qui est écrit, on aura du mal à le jeter à la poubelle même si on a le temps de le ré-écrire.
On a plus un problème d'attachement à ce qu'on a écrit plus qu'un problème de temps passé.
D'autre part, il faut prendre en compte la formation des développeurs par l'expérimentation. Des cas où j'ai laissé des gens faire plus compliqué que nécessaire en me disant que cela aurait des vertus de formation, y'en a plein. Derrière c'est vrai que tu traines un code trop complexe, mais au moins la personne s'est formée, et si le module n'est pas critique, pourquoi pas.