Misères de la conception objet : notes et arrière-pensées
par
, 03/03/2015 à 09h26 (1141 Affichages)
Quelques idées venues en écrivant le message précédent, livrées en vrac.
Que nous apprend l’exemple du poker ? Plusieurs choses à mon avis.
D’abord, que l’imitation du réel, qui nous vient naturellement quand on conçoit un programme, ne donne pas forcément la meilleure solution, ni même une bonne solution. C’était le sujet de l’article, inutile d’y revenir.
Ensuite, que notre architecture s’est améliorée en passant d’une description « physique » du problème (les cartes et les mains), à une description plus algorithmique (les figures et la fonction de comparaison), à la représentation des données nécessaires au fonctionnement de l’algorithme (les « mains triées »).Je crois que ces trois étapes sont au cœur de toute conception informatique. Pour écrire un programme, on part d’une description naïve du réel, qu’on doit abandonner pour une vision plus algorithmique de ses règles de fonctionnement (ou plus précisément, de la partie des règles de fonctionnement qui nous importent),qu’on doit à nouveau abandonner pour une réflexion sur la représentation des données, dont on tire l’architecture finale.
Dans la pratique, la dernière étape est souvent reportée à des jours meilleurs (c’est-à-dire jamais…), car elle est vue comme une « optimisation prématurée ». C’est à mon avis une très mauvaise idée (et un bien mauvais procès fait à Knuth). La réflexion sur les données, on le voit dans l’exemple du poker, et une façon de revenir sur les algorithmes, et d’arriver à une architecture plus simple (et plus facile à maintenir).
En fait, la seconde étape est souvent bâclée, elle aussi. Une fois qu’ils ont la description naïve du système, beaucoup de développeurs se précipitent sur Google (ou DVP) pour y chercher des solutions en boîte, librairies toutes faites, ou solutions à appliquer aveuglément (c’est exactement l’idée des design pattern). Ceci part d’un bon sentiment, mais prise trop tôt, cette recherche de solutions toutes faites tue la conception en la figeant prématurément (parce qu’une fois qu’on aura décidé que c’est un problème de « cartes » et qu’on aura choisi la librairie cartelib.dll qui modélise toutes les cartes possibles et imaginables, il sera très difficile d’abandonner la conception, au profit d’une autre fondée sur les figures…)
Et ceci m’amène à ce qui devrait peut-être être la vraie conclusion du billet précédent. La conception d’un programme part presque toujours d’une architecture naïve, qu’on critique et qu’on abandonne au profit d’une vision plus profonde, qu’on abandonnera probablement elle aussi pour une troisième. Plus le programme est important, plus il y aura d’itérations, et en général, très peu de code doit survivre d’une itération à l’autre (personnellement, je réécris complètement à chaque fois…).
Je ne crois pas qu’on puisse se passer de ces étapes. En fait, je crois même que c’est en persistant longtemps dans une mauvaise idée qu’on finit par en comprendre les limites, et trouver une meilleure solution. Il faudra alors accepter de jeter ce qu’on à fait, donc probablement ne pas trop fignoler ces premières étapes, sous peine de trop s’attacher aux mauvaises solutions du début.
Les mauvaises idées sont le fumier sur lequel poussent les bons programmes.
Pour ceux que la conception objet intéresse, je ne saurai trop recommander les écrits et les vidéos de Sandi Metz. C’est du Ruby et pas du C++, il y a un peu trop de tests unitaires à mon goût (j’y reviendrai), mais c’est toujours très clair. Dans les grands anciens, je recommande Brad Cox (l’inventeur de l’objective C) : Object Oriented Programming: An Evolutionary Approach.