Ma version de "comment limiter l'over-engineering"
Définir le niveau d'engineering logiciel attendu
Tout comme un logiciel s'adresse à un public, un code source s'adresse à un public de développeurs.
Est-ce que l'équipe qui développe a vocation à être composée uniquement d'expert du language / de la technologie ? Est-ce que l'équipe est pluri-disciplinaire ? Est-ce que des débutants voire - allez soyons fous, des non-développeurs doivent intervenir et/ou comprendre le code source ?
Exemple : lorsque j'interviens sur des projets en Django, je refuse a priori d'utiliser les signaux. Pourquoi ? Parce que dans 90% des cas, c'est un mécanisme qui n'est pas nécessaire (on peut le remplacer par un appel explicite), et dans 100% des cas ça complique la compréhension du code. Certes, c'est un beau concept ; mais on peut faire la même chose avec des outils simples, alors pourquoi s'en priver ?
Autre exemple : je veux que le code développé par mon équipe soit autant que possible compréhensible par un débutant. Ce n'est pas toujours le cas, mais souvent cela limite la complexité autorisée et finalement, le résultat est le même (je ne travaille pas sur des sujets algorithmiques).
Favoriser la compréhension vs la "beauté" du code
Le fameux "DRY" (don't repeat yourself - ne te répète pas), les abstractions, la méta-programmation... cela rend le code aussi compliqué à comprendre/maintenir qu'un code monolithique développé par des débutants.
La factorisation doit intervenir quand elle apporte un réel plus, et quand elle ne nuit pas à la compréhension du code.
Une séance de debug qui nécessite de passer de plus de 3/4 fonctions/méthodes pour comprendre un mécanisme est significative d'un code trop complexe.
Avoir une bonne vision du projet, et la communiquer clairement
Avoir une bonne vision du projet permet de décider des développements nécessitant de l'anticipation (en terme d'architecture) et ceux qui n'en nécessitent pas. C'est parfois clair pour le décideur / chef de projet / responsable du développement, mais il faut aussi que les développeurs le sachent. Et quand ça ne l'est pas pour les responsables, deux possibilités : soit ils cherchent l'info et la trouve et on retombe dans le cas précédent, soit l'anticipation n'est en général pas une bonne idée.
Ne pas optimiser le code
Souvent je vois des développeurs qui anticipent des problématiques de performance. Genre "Ah oui mais dans ce cas-là on peut améliorer la perf en faisant ceci ou cela". Résultat : un algorithme avec 2 cas de figure au lieu d'un. Sans intelligence supplémentaire, juste une pseudo-optimisation... qui bien souvent n'est pas un goulot d'étranglement.
Quand on ne sait pas quels sont les goulots d'étranglement, on n'optimise pas.
L'optimisation de code / algorithme est un travail de spécialiste. Si ton boulot n'est pas celui-ci, alors produits du code non optimisé ; tu l'optimiseras plus tard si c'est vraiment nécessaire.
Ecrire du code ready-to-refactor
Les développeurs veulent souvent faire un truc "nickel" dès le début. Hors, comme on ne sait pas comment le code va évoluer, on est tenté d'implémenter toute sortes d'abstractions et de flexibilités qui compliquent la compréhension du code.
Le refactoring fait partie du travail quotidien d'un développeur ; la difficulté est de produire du code "rapidement fonctionnel, mais évolutif via refactoring". Comme ce que dit Fransceco un peu plus haut.
Souvent cela passe par faire un code propre, "sauf là, à cet endroit c'est vraiment dégueu mais c'est là qu'on va refactoriser par la suite" pour le rendre plus souple.
C'est un peu comme les "fusibles" dans la structure des voitures haut de gamme : les grosses berlines sont conçues pour "casser à certains endroits" de manière à garder l'habitacle et ses passagers sains et saufs. Dans le code c'est pareil : il faut anticiper ce qui peut/doit être cassé et garder les algorithmes dont la complexité immédiate est nécessaire aussi monolithiques que possibles.
Mais en vrai, une bonne vieille dictature...
Au final, je pense qu'un bon dictateur sera un excellent moyen de limiter l'over-engineering. Et un bon dictateur sera souvent un développeur pas trop passionné de code, ou en tout cas sensible aux problématiques business/délais/coûts tout autant que développement.
#tracim pour la collaboration d'équipe __ #galae pour la messagerie email __ dirigeant @ algoo
# chi va piano va sano
Posté par LeBouquetin (site web personnel, Mastodon) . En réponse au journal Lutter contre l'overengineering. Évalué à 10.
Ma version de "comment limiter l'over-engineering"
Définir le niveau d'engineering logiciel attendu
Tout comme un logiciel s'adresse à un public, un code source s'adresse à un public de développeurs.
Est-ce que l'équipe qui développe a vocation à être composée uniquement d'expert du language / de la technologie ? Est-ce que l'équipe est pluri-disciplinaire ? Est-ce que des débutants voire - allez soyons fous, des non-développeurs doivent intervenir et/ou comprendre le code source ?
Exemple : lorsque j'interviens sur des projets en Django, je refuse a priori d'utiliser les signaux. Pourquoi ? Parce que dans 90% des cas, c'est un mécanisme qui n'est pas nécessaire (on peut le remplacer par un appel explicite), et dans 100% des cas ça complique la compréhension du code. Certes, c'est un beau concept ; mais on peut faire la même chose avec des outils simples, alors pourquoi s'en priver ?
Autre exemple : je veux que le code développé par mon équipe soit autant que possible compréhensible par un débutant. Ce n'est pas toujours le cas, mais souvent cela limite la complexité autorisée et finalement, le résultat est le même (je ne travaille pas sur des sujets algorithmiques).
Favoriser la compréhension vs la "beauté" du code
Le fameux "DRY" (don't repeat yourself - ne te répète pas), les abstractions, la méta-programmation... cela rend le code aussi compliqué à comprendre/maintenir qu'un code monolithique développé par des débutants.
La factorisation doit intervenir quand elle apporte un réel plus, et quand elle ne nuit pas à la compréhension du code.
Une séance de debug qui nécessite de passer de plus de 3/4 fonctions/méthodes pour comprendre un mécanisme est significative d'un code trop complexe.
Avoir une bonne vision du projet, et la communiquer clairement
Avoir une bonne vision du projet permet de décider des développements nécessitant de l'anticipation (en terme d'architecture) et ceux qui n'en nécessitent pas. C'est parfois clair pour le décideur / chef de projet / responsable du développement, mais il faut aussi que les développeurs le sachent. Et quand ça ne l'est pas pour les responsables, deux possibilités : soit ils cherchent l'info et la trouve et on retombe dans le cas précédent, soit l'anticipation n'est en général pas une bonne idée.
Ne pas optimiser le code
Souvent je vois des développeurs qui anticipent des problématiques de performance. Genre "Ah oui mais dans ce cas-là on peut améliorer la perf en faisant ceci ou cela". Résultat : un algorithme avec 2 cas de figure au lieu d'un. Sans intelligence supplémentaire, juste une pseudo-optimisation... qui bien souvent n'est pas un goulot d'étranglement.
Quand on ne sait pas quels sont les goulots d'étranglement, on n'optimise pas.
L'optimisation de code / algorithme est un travail de spécialiste. Si ton boulot n'est pas celui-ci, alors produits du code non optimisé ; tu l'optimiseras plus tard si c'est vraiment nécessaire.
Ecrire du code ready-to-refactor
Les développeurs veulent souvent faire un truc "nickel" dès le début. Hors, comme on ne sait pas comment le code va évoluer, on est tenté d'implémenter toute sortes d'abstractions et de flexibilités qui compliquent la compréhension du code.
Le refactoring fait partie du travail quotidien d'un développeur ; la difficulté est de produire du code "rapidement fonctionnel, mais évolutif via refactoring". Comme ce que dit Fransceco un peu plus haut.
Souvent cela passe par faire un code propre, "sauf là, à cet endroit c'est vraiment dégueu mais c'est là qu'on va refactoriser par la suite" pour le rendre plus souple.
C'est un peu comme les "fusibles" dans la structure des voitures haut de gamme : les grosses berlines sont conçues pour "casser à certains endroits" de manière à garder l'habitacle et ses passagers sains et saufs. Dans le code c'est pareil : il faut anticiper ce qui peut/doit être cassé et garder les algorithmes dont la complexité immédiate est nécessaire aussi monolithiques que possibles.
Mais en vrai, une bonne vieille dictature...
Au final, je pense qu'un bon dictateur sera un excellent moyen de limiter l'over-engineering. Et un bon dictateur sera souvent un développeur pas trop passionné de code, ou en tout cas sensible aux problématiques business/délais/coûts tout autant que développement.
#tracim pour la collaboration d'équipe __ #galae pour la messagerie email __ dirigeant @ algoo