« Quelque chose ne va vraiment pas avec les développeurs "modernes" »
Un développeur à "l'ancienne" critique la multiplication des bibliothèques

Les rubriques (actu, forums, tutos) de Développez
Réseaux sociaux


 Discussion forum

Le , par Hinault Romaric, Responsable Actualités
William Edwards, un développeur “senior” attire l’attention dans un article de blog sur les choix des développeurs qu’il appelle « modernes » et qui pour lui auraient de très mauvais effets sur l’industrie.

Les développeurs opteraient de plus en plus pour une multitude de bibliothèques externes modernes pour la conception d’une application.

Ces bibliothèques, bien qu’offrant chacune de bonnes performances, seraient utilisées sans une réelle maîtrise des spécificités de celles-ci, et le produit qui en ressortirait serait souvent complexe, et dans la plupart des cas assez difficile à maintenir voire peu performant.

William Edwards part d’un commentaire d’un lecteur sur un article qui expliquait comment l’outil NooSFere peut comprimer à 90% des emails.

L’application NooSFere utilise un cache avec l’algorithme LRU (Least Recently Used). Les mails deviennent une liste de pointeurs de chaine partagée et la compression est effectuée en arrière-plan en utilisant l’algorithme de compression de données LZMA (Lempel-Ziv-Markov chain-Algorithm).

L’utilisation uniquement des ressources du langage (table de hachage Java normale et listes liées) ayant permis un gain de performance énorme a été cependant critiquée par un développeur.

Celui-ci dans son commentaire se demande pourquoi Redis (système de gestion de base de données NoSQL, clef-valeur libre, scalable, hautes performances) n’a pas été utilisé dans le projet pour la LRU. Proposition qui est soutenue par une autre personne qui trouve que Redis couplé à node.js sont connus pour être assez performants. Donc, une orientation vers une solution Web.

« Les projets sont de plus en plus des sites Web » regrette Edwards, qui ajoute. « Vous n’avez pas besoin d’être un puissant programmeur. Vous pouvez utiliser JavaScript, exécuter node.js et utiliser MongoDB ou Redis en arrière-plan et vous pensez que votre solution est performante ? ».

De façon générale pour William Edwards, les développeurs optent beaucoup plus pour la facilité que pour la simplicité. Résultat, ils se retrouveraient très souvent avec des solutions complexes disposant de plusieurs briques logicielles (bases de données NoSQL, interfaces, divers scripts issus des copier/coller, bibliothèques d’accès aux données, etc.) et peu performantes.

« Il y a une nouvelle mentalité – un mouvement moderne – le développement d’une application revient à réfléchir sur comment relier une constellation de composants logiciels différents […] ils veulent utiliser tous les nouveaux outils qui brillent» conclut Edwards.

Pour lui, il serait presque toujours préférable d’utiliser une base de données locale (sqllite, levelDB, BDB etc.), un langage rapide reposant sur un runtime (et éviter les langages dynamiques), et utiliser le moins de machines possible pour effectuer une transaction (le premier ennemi de la performance serait le nombre de machines).

Bref, un avis tranché qui ressemble fort à une incompréhension générationnelle. Mais qui n’est pas dénué d’analyse.

Un avis, en tout cas, qui suscite débat et réactions.

Le billet de blog William Edwards

Et vous ?

Partagez-vous le point de vue de William Edwards ?

Pensez-vous que le choix de plusieurs outils récents pour développer un produit n’est pas le meilleur ?

Vous reconnaissez-vous dans sa définition d’un “développeur moderne” ? Et que lui répondriez-vous ?


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de arkhamon arkhamon
http://www.developpez.com
Membre Expert
le 18/12/2012 12:31
Et pour finir (parce que je sens que mon ulcère revient à la surface...), ce qui est malheureusement vrai en informatique l'est aussi souvent dans d'autres domaines :

  • c'est pas grave de fixer une lamelle d'alu avec des rivets à la con, c'est pas moi qui réparerai après. Crash du Concorde et 150 morts.
  • Ca coute cher de chauffer le sang transfusé, pas grave, y a pas de risque. Des milliers de personnes contaminées et condamnées à mort.
  • Si on fait des tests anti-SIDA sur le sang transfusé, on va perdre du temps et du coup on devra verser des dividendes çà une société US. Des milliers de personnes contaminées et condamnées à mort.
  • Pas la peine de s'occuper de l'amiante, les autres le feront bien après. Des milliers de personnes contaminées et condamnées à mort.
  • Je suis un état et je veux faire plaisir à tout le monde, j'emprunte bien au dessus de ce que je peux supporter. Pas grave, les suivants se démerderont. La Grêce est au bord de la faillite, entrainant avec elle 350 millions de personnes.
  • Ma fonction de calcul n'est pas initialisée avec une valeur de sortie par défaut compatible. Pas grave, l'appelant n'a qu'à se débrouiller pour vérifier. Sauf que le taux valant 0, ça a planté et ça a scotché 10 personnes pendant toute une nuit pour récupérer le coup.

Vous en voulez d'autres ? Je peux y passer la nuit...
Avatar de el_slapper el_slapper
http://www.developpez.com
Expert Confirmé Sénior
le 18/12/2012 14:15
Citation Envoyé par arkhamon  Voir le message
C'est bien ce que je dis : je fais de la merde et je m'en fous parce que c'est pas moi qui devrai gérer par la suite.

Non. Je fais un truc rapide parceque si je perds du temps à faire "propre", je suis mort(c'est spécifique aux start-up).

Encore une fois, moi, je n'ai jamais été dans cette situation-là. Même sous pression(tu nous fais ce programme de 10 jours en deux jours), j'ai toujours pu me permettre de faire de la présentation, un peu d'archi, un peu de commentaire. De la doc, faut pas rêver, hélas. De toutes façons, les rares fois ou j'ai eu l'occasion d'en faire, elle a été perdue, alors... Mais j'ai toujours codé/commenté en me disant "si je reviens dans dix ans, qu'est-ce que je vais retrouver?"

Celà étant, je comprends ta fureur. Je fais surtout de la maintenance, et les développeurs "trop fort pour perdre leur temps en maintenance" qui crachent des immondices inmaintenables en croyant être des surdieux alors qu'ils ne sont que des surboulets, ça rejoint ce que tu décris.

Mais c'est plus, à mon sens, une question de parcours personel qu'une question de formation ou de méthodes : une fois qu'on a forçé le gars à maintenir un gros monstre hideux, qu'il aura vu les limites de ses architectures astronautiques, et compris pourquoi un code doit être compréhensible même par un imbécile, alors il fera mieux. Seulement, à force de persuasion, ils sont nombreux à toujours y échapper.

Il y a aussi de développeur qui sort d'école/fac, qui a la tête pleine de beaux principes, et que l'on fout sur un projet sans supervision(sinon c'est trop cher). Fatalement, il va faire "au mieux", c'est-à-dire qu'il va surconcevoir et surcharger son système, tout en s'appliquant.

Et de toutes façons, qui que ce soit qui fasse "au mieux", ça sera toujours de la merde pour les autres.....
Avatar de yann2 yann2
http://www.developpez.com
Membre Expert
le 18/12/2012 14:21
Citation Envoyé par arkhamon  Voir le message
Et pour finir (parce que je sens que mon ulcère revient à la surface...), ce qui est malheureusement vrai en informatique l'est aussi souvent dans d'autres domaines :

  • c'est pas grave de fixer une lamelle d'alu avec des rivets à la con, c'est pas moi qui réparerai après. Crash du Concorde et 150 morts.
  • Ca coute cher de chauffer le sang transfusé, pas grave, y a pas de risque. Des milliers de personnes contaminées et condamnées à mort.
  • Si on fait des tests anti-SIDA sur le sang transfusé, on va perdre du temps et du coup on devra verser des dividendes çà une société US. Des milliers de personnes contaminées et condamnées à mort.
  • Pas la peine de s'occuper de l'amiante, les autres le feront bien après. Des milliers de personnes contaminées et condamnées à mort.
  • Je suis un état et je veux faire plaisir à tout le monde, j'emprunte bien au dessus de ce que je peux supporter. Pas grave, les suivants se démerderont. La Grêce est au bord de la faillite, entrainant avec elle 350 millions de personnes.
  • Ma fonction de calcul n'est pas initialisée avec une valeur de sortie par défaut compatible. Pas grave, l'appelant n'a qu'à se débrouiller pour vérifier. Sauf que le taux valant 0, ça a planté et ça a scotché 10 personnes pendant toute une nuit pour récupérer le coup.

Vous en voulez d'autres ? Je peux y passer la nuit...

Bonjour

Il y a une différence entre faire une optimisation largement mineure et réaliser une analyse safety. On approche du point Godwin là.

Yann
Avatar de arkhamon arkhamon
http://www.developpez.com
Membre Expert
le 18/12/2012 15:48
Citation Envoyé par yann2  Voir le message
Bonjour

Il y a une différence entre faire une optimisation largement mineure et réaliser une analyse safety. On approche du point Godwin là.

Yann

Ce que je voulais illustrer, c'est qu'il en va de même pour un code propre (j'entends par la lisible, et surtout débuggé au maximum, le programme parfait n'existant pas) que pour le reste : on va gentiement vers un laxisme généralisé ou "pas grave de faire attention, les autres régleront le problème".

Faire un soft pas optimisé, en soi n'est pas grave, jusqu'au moment ou ce manque d'optimisation pénalise la suite. Ce qui à la fin finit bien souvent par arriver. Et là l'argument imparable : " ben oui mais moi j'ai pas de budget pour corriger". Alors que si on fait les choses proprement dès le départ...

Pour moi, appeler le même getter avec les mêmes paramètres dans une boucle, c'est pas une source (potentielle d'après certains) d'optimisation, c'est de l'incompétence profonde.

De la même façon que ce code là :
Code :
1
2
3
4
5
 
For i := 0 to XMLDoc.root.node('Toto').node('Tata').childs.count - 1 do 
  Begin 
    showmessage(XMLDoc.root.node('Toto').node('Tata').childs[i].Text); 
  end;

devrait être remplacé par (ou plutôt dès le départ) :
Code :
1
2
3
4
5
6
7
 
Var Monnode : XmlNode; 
MonNode := XMLDoc.root.node('Toto').node('Tata'); 
For i := 0 to MonNode.childs.count - 1 do 
  Begin 
    showmessage(MonNode.childs[i].Text); 
  end;

On gagnera dans ce cas à chaque fois le parcours partiel de l'arbo XML...

Sans parler des blocs Try-Except-Finally qu'on va économiser. Encore que moi j'utilise pas donc...
Avatar de el_slapper el_slapper
http://www.developpez.com
Expert Confirmé Sénior
le 18/12/2012 16:27
Citation Envoyé par arkhamon  Voir le message
Ce que je voulais illustrer, c'est qu'il en va de même pour un code propre (j'entends par la lisible, et surtout débuggé au maximum, le programme parfait n'existant pas) que pour le reste : on va gentiement vers un laxisme généralisé ou "pas grave de faire attention, les autres régleront le problème".

C'est marrant, en fait, on est presque d'accord...

Citation Envoyé par arkhamon  Voir le message
Faire un soft pas optimisé, en soi n'est pas grave, jusqu'au moment ou ce manque d'optimisation pénalise la suite. Ce qui à la fin finit bien souvent par arriver. Et là l'argument imparable : " ben oui mais moi j'ai pas de budget pour corriger". Alors que si on fait les choses proprement dès le départ...

C'est juste là que nous avons une différence. Il peut arriver que si on prend le temps de faire les choses proprement, on soit mort.

Mais bon, ça n'est pas le cas général. Le cas général, c'est que la boite va probablement survivre, et que le code va donc probablement survivre. Dans ces conditions(qui sont les plus fréquentes), il FAUT faire propre.

Citation Envoyé par arkhamon  Voir le message
Pour moi, appeler le même getter avec les mêmes paramètres dans une boucle, c'est pas une source (potentielle d'après certains) d'optimisation, c'est de l'incompétence profonde.

+1

Citation Envoyé par arkhamon  Voir le message
De la même façon que ce code là :
Code :
1
2
3
4
5
 
For i := 0 to XMLDoc.root.node('Toto').node('Tata').childs.count - 1 do 
  Begin 
    showmessage(XMLDoc.root.node('Toto').node('Tata').childs[i].Text); 
  end;

devrait être remplacé par (ou plutôt dès le départ) :
Code :
1
2
3
4
5
6
7
 
Var node : XmlNode; 
Node := XMLDoc.root.node('Toto').node('Tata'); 
For i := 0 to Node.childs.count - 1 do 
  Begin 
    showmessage(Node.childs[i].Text); 
  end;

On gagnera dans ce cas à chaque fois le parcours partiel de l'arbo XML...

C'est un peu comme mon exemple, ou on économise des parcours du tableau EXCEL. Mais j'insiste : il faut faire de l'analyse de la valeur, et savoir ce qui est le plus important.

Citation Envoyé par arkhamon  Voir le message
Sans parler des blocs Try-Except-Finally qu'on va économiser. Encore que moi j'utilise pas donc...

Tiens, tu appartiens à l'école anti-exceptions de Joel Spolsky?

EDIT : tiens, tant que j'y pense, en football, on apprend aux débutants à ne JAMAIS utiliser la pointe du pied pour tirer : c'est moche, et surtout c'est imprécis. Un jeu propre implique d'utiliser systématiquement l'intérieur du pied, bien plus précis. Le pointu, c'est un peu le GOTO du football.

En finale de la coupe du monde 2002, le but vainqueur a été inscrit par Ronaldo. Sur un vilain pointu méchant. Parceque le ballon était fuyant et que Ronaldo ne pouvait pas se permettre de le jouer de l'intérieur du pied, le temps de contrôler, le gardien aurait été sur lui.

Donc, mon argument, c'est que dans des circonstances exceptionelles, on peut être amené à s'assoir sur les règles. Mais évidemment, il faut considérer que les circonstances exceptionelles, euh, en général, c'est pas maintenant. Et appliquer les règles. Et tirer de l'intérieur du pied.
Avatar de arkhamon arkhamon
http://www.developpez.com
Membre Expert
le 18/12/2012 16:33
Citation Envoyé par el_slapper  Voir le message
C'est marrant, en fait, on est presque d'accord...

Comme quoi de temps en temps...

Citation Envoyé par el_slapper  Voir le message

Heu... Non... juste un peu fainéant... En même temps, je développe pour moi et mes potes, donc mon soft peut ne pas être très solide si on taquine ses fichiers de données, c'est pas trop grave. Après moi le déluge...
Toute blague mise à part, en environnement pro, je pense pas qu'on puisse se permettre ce genre de légèreté.
Avatar de yann2 yann2
http://www.developpez.com
Membre Expert
le 18/12/2012 17:08
Bonjour

arkhamon, pour ton exemple je suis tout à fait d'accord. D'ailleurs je n'appelle pas ça de l'optimisation ça fait parti de l'algo lui même ce genre de problème.

Il ne faut pas confondre parcours de listes et filtres sur ces même listes avec un simple accesseur. J'ai dit plus haut que getXxxx devrait, dans l'idéal, seulement retourner Xxxx.

Dans ton exemple la méthode s'appellerait plutôt findNode(nodeName) et là, il n'y a pas d'excuse si le développeur l'appelle dans la boucle (et c'est même pire que de l'incompétence à mon avis, à moins que ce soit une étourderie). Perso, je n'ai pas de collègues qui font ce genre d'erreurs.
Avatar de arkhamon arkhamon
http://www.developpez.com
Membre Expert
le 19/12/2012 8:56
Citation Envoyé par yann2  Voir le message
Dans ton exemple la méthode s'appellerait plutôt findNode(nodeName) et là, il n'y a pas d'excuse si le développeur l'appelle dans la boucle (et c'est même pire que de l'incompétence à mon avis, à moins que ce soit une étourderie).

En fait, elle s'appelle SelectSingleNode car je n'utilise pas la librairie intégrée de FireMonkey elle est trop pourrie. J'utilise OmniXML de Ondrej Pokorny qui est largement meilleure. Mais l'esprit est le même...
Citation Envoyé par yann2  Voir le message
Perso, je n'ai pas de collègues qui font ce genre d'erreurs.

Moi non plus je te rassure, ils ne font pas ça. Ils font pire...
Avatar de rimram31 rimram31
http://www.developpez.com
Membre confirmé
le 19/12/2012 10:43
Citation Envoyé par arkhamon  Voir le message
...Moi non plus je te rassure, ils ne font pas ça. Ils font pire...

Dans l'exemple que je cite plus haut, il s'agit d'une équipe, et d'ailleurs différente dans le temps. Une partie a écrit le layer bdd, d'autres l'utilisent et, a quelques mauvais choix de nom de méthode près (get vs load par exemple) fait la boulette et l'accentue en pensant qu'un getXXX ne fait que retourner un attribut alors qu'elle attaque à chaque fois la BDD, au sacro saint principe qu'il faut avoir des données "à jour" et quand tu dis ensuite que la bdd est trop chargée, on t'explique qu'il "suffit" de rajouter des serveurs bdd et te sortent toute une théorie sur la répartition de charge ... (a laquelle d'ailleurs le plus souvent, ils n'entendent pas grand chose, chacun son job!)

Souvenir d'une astuce utilisée alors où je m'étais contenté de mettre en cache (accroché au thread java! pas beau, c'est en plein dans le sujet) et où j'avais divisé par deux ou par trois la charge bdd en 10 lignes de code. Sacré économie pour quelques lignes ...
Avatar de el_slapper el_slapper
http://www.developpez.com
Expert Confirmé Sénior
le 19/12/2012 11:47
Citation Envoyé par rimram31  Voir le message
(.../...) et l'accentue en pensant qu'un getXXX ne fait que retourner un attribut alors qu'elle attaque à chaque fois la BDD, au sacro saint principe qu'il faut avoir des données "à jour" (.../...)

Errare humanum est, perseverare diabolicum.

D'autant plus que dans un paragraphe donné(fonction, méthode, que sais-je, un paquet de code unitaire quelconque), l'algorithme présuppose généralement que la donnée de change pas. Il peut y avoir des exceptions, mais il me semble que, dans le cas général, si l'entrée change en cours de paragraphe, on est mal.

Si je commence à afficher la cliente Mademoiselle Martin, et qu'en cours de traitement, elle devient Madame Michu, on aura un affichage incohérent(du genre Mademoiselle Michu pour un getTitre & getPatronyme). Mieux vaut un affichage obsolète(au pire, l'agent rafraichit son écran, et Madame Michu remplace Mademoiselle Martin) qu'incohérent.

Pour en revenir aux performances, sous COBOL/MVS, 99,9% des soucis de performances viennent des accès référentiels. De ce que je lis ici ou là, dans d'autres technologies, c'est presque autant. C'est encore une raison pour laquelle le vieil adage "(1)dont optimize; (2 - experts only), don't optimize yet" ne s'applique pas aux référentiels. Et c'est là qu'on en revient au sujet de base de ce fil : quand les appels référentiels sont complètement masqués par des surcouches nombreuses et peu maitrisées, on en arrive à du Bloatware. Qui est souvent(pas toujours) facile à éviter.

Sur mon exemple des 6 heure d'accès référentiel, j'ai mis cinq fois dix lignes(une fois par référentiel appelé), et j'ai gagné 1 heure. (hyper compliqué : je copie la zone d'entrée et la zone de sortie, et si la zone d'entrée est la même que précédemment, je met la zone de sortie au lieu de mouliner). C'est facile, lisible, et ça rapporte gros(les gens qui valident les résultats sont contents de l'avoir à 16 heures au lieu de 17 heures). A noter que mes accès sont en grande partie masqués : je fait appel à un module d'accès qui me renvoie les données. Je ne sais pas ce qu'il y a dedans. Un peu comme ma fonction Excel qui me renvoie la dernière ligne utile du tableau.

Mais je SAIS que c'est du référentiel. Donc je fais gaffe quand même. La bufferisation de l'appel précédent est presque toujours une bonne habitude - facile, pas cher, lisible, et qui rapporte gros. MaDonnee = GetMaDonnee(param), c'est une forme primitive, brutale, mais hypersimple et très efficace de bufferisation.
Avatar de rimram31 rimram31
http://www.developpez.com
Membre confirmé
le 19/12/2012 12:48
Citation Envoyé par el_slapper  Voir le message
Errare humanum est, perseverare diabolicum....

Ca rejoint le commentaire d'arkhamon "après moi le déluge", comme gérer la cohérence coté applicatif, ça peut devenir compliqué (surtout si on fait aucun effort!), je laisse la BDD s'en débrouiller et après j'engueule les opé et cette même BDD parce qu'elle ne parvient pas a s'en sortir ...

Sur un service web, c'est pas idiot de faire une "photo" des données à l'entrée d'une requête, surtout qu'elle doit répondre, par principe, dans un temps très court. Ca dépend du type de service, mais j'ai travaillé sur des implémentations de cache dits "dirty", où on met à jour certaines données, pas du tout critiques, a des périodes données indépendamment du trafic. C'est facile, ça coute pas cher (genre if elapsed() > ...) et ça peut faire un bien fou a une plateforme.

Mais ma remarque rejoint mes posts plus hauts où j'ai le sentiment que, certains, développeurs n'ont pas grossièrement en tête le coût des traitements qu'ils codent. Il est parfois difficile de se l'imaginer "a priori", raison de plus pour avoir quelques bonnes habitudes qui prémunissent en partie de certaines surprises.
Offres d'emploi IT
Développeur Passionné Java H/F
CDI
ZENIKA - Ile de France - Rennes (35000)
Parue le 01/08/2014
Développeur .net activement recherché pour un éditeur innovant en recherche de talents !!
CDI
Easy Partner - Ile de France - Paris (75000)
Parue le 20/08/2014
Analyste développeur mainframe h/f
CDI
EXPERIS IT - Centre - Région Centre
Parue le 30/07/2014

Voir plus d'offres Voir la carte des offres IT
 
 
 
 
Partenaires

PlanetHoster
Ikoula