Comment puis-je éviter de toujours avoir l'impression que si je reconstruisais complètement mon programme, je le ferais beaucoup mieux? [fermé]


91

J'ai appris beaucoup de choses à coder, cependant, cela a toujours été dans un environnement scientifique (pas informatique), complètement autodidacte, sans que personne ne puisse me guider dans la bonne direction. Ainsi, mon parcours de codage a été… compliqué. Je remarque maintenant que chaque fois que je construis un type de programme, à la fin, je me rends compte que j’aurais pu le faire beaucoup plus élégamment, beaucoup plus efficacement et d’une manière beaucoup plus souple et facile à gérer. Dans certaines circonstances, je suis effectivement revenu en arrière et ai reconstruit les choses à partir de la base, mais cela n’est généralement pas faisable dans la pratique. Jusqu'à présent, la plupart de mes programmes étaient relativement petits, mais il semble difficile de réécrire complètement de gros programmes chaque fois que vous créez quelque chose.

Je me demande si c'est une expérience normale? Si non, comment empêchez-vous cela? J'ai essayé de planifier les choses à l'avance, mais je n'arrive pas à tout prévoir avant de commencer à élaborer du code.


87
sa normale, programme plus
Ewan



43
Bienvenue à la programmation. Si vous ne regardez pas l'ancien code et pensez "urgh", vous devriez commencer à vous inquiéter car cela signifie que vous avez arrêté d'apprendre.
Caltor

9
Honnêtement, quand j'ai vu cette question, j'ai ri - parce que, littéralement, tous les programmeurs à qui j'ai parlé, y compris moi-même, ont ce sentiment constamment et à tout moment. Si vous vouliez vous rendre dans un domaine où vous pensiez que le produit final que vous fabriquiez ne présentait aucun défaut - la programmation était le mauvais domaine à choisir.
Zibbobz

Réponses:


4

Ce sentiment est tout à fait normal et attendu. Cela signifie que vous apprenez. Presque chaque fois que je commence un nouveau projet, je commence dans une direction et je finis par le concevoir différemment à la fin.

Il est courant de commencer par développer un prototype avant de commencer avec la réalité. Il est également courant de revoir l'ancien code et de le reformuler . Cela est plus facile si votre conception est modulaire - vous pouvez facilement redessiner des éléments à la fois sans avoir à supprimer totalement votre ancienne conception.

Pour certaines personnes, il est utile d’écrire d’abord le pseudo-code . D'autres trouvent utile de commencer par écrire des commentaires décrivant ce que le code va faire, puis d'écrire le code une fois que la structure générale est présente. Ces deux éléments vous aideront à mieux planifier votre conception et vous éviteront peut-être une réécriture.

Si vous faites partie d'une équipe, un processus de révision est crucial pour le processus de conception. Demandez à quelqu'un de revoir votre code afin que vous puissiez apprendre comment améliorer votre conception.


100

C'est une expérience très commune

La plupart des gens avec qui j'interagis et moi-même me sentent comme ça. D'après ce que je peux en dire, l'une des raisons est que vous en apprenez plus sur le domaine et les outils que vous utilisez lors de l'écriture de votre code, ce qui vous amène à reconnaître de nombreuses possibilités d'amélioration après avoir écrit votre programme.

L'autre raison est que vous avez peut-être une idée en tête de la solution de code propre idéale, puis que le monde réel et ses limitations complexes vous gênent, vous obligeant à écrire des solutions de contournement imparfaites et des hacks qui pourraient vous laisser insatisfaits.

"Tout le monde a un plan jusqu'à ce qu'ils soient frappés au poing."

Que faire à ce sujet

Dans une certaine mesure, vous devrez apprendre à accepter que votre code ne sera jamais parfait. La chose qui m'a aidé à cela est la mentalité de "Si je déteste le code que j'ai écrit il y a un mois, cela signifie que j'ai appris et que je suis devenu un meilleur programmeur".

Un moyen d'atténuer le problème consiste à être constamment à l'affût d'améliorations potentielles pendant que vous travaillez et refactorisez en permanence. Assurez-vous de trouver un bon équilibre entre la refactorisation et l'ajout de nouvelles fonctionnalités / la correction de bugs. Cela ne réglera pas les gros problèmes de conception, mais vous aurez généralement une base de code plus élaborée dont vous pourrez être fier.


18
La seule chose que je voudrais ajouter à cette réponse est, apprendre et suivre les principes de TDD lors de la rédaction de code. Ces tests fournissent ensuite un environnement sécurisé pour la refactorisation et la réécriture à mesure que vous continuez à vous améliorer en tant que développeur et que vous souhaitez apporter des modifications au code existant.
David Arno

10
@DavidArno quel est l'intérêt de refactoriser avec les tests présents? C'est comme mettre à jour un système et faire une sauvegarde avant ... 0 amusement.
jeudi

3
@ Džuris, :) Certes, si vous aimez les défis, n'écrivez pas de tests
David Arno

6
@ Džuris C'est comme sauter d'un avion vêtu d'un parachute!
JollyJoker

3
@jamesqf - C'est une description erronée de ce que font TDD et les tests unitaires - ils peuvent par exemple vous dire que votre modèle ou algorithme est correctement implémenté et que vous n'avez rien cassé lors de votre refactorisation. Ils ne peuvent pas vous dire que votre modèle est réellement utile. C'est aussi vrai dans un environnement scientifique que dans n'importe quel autre.
Ant P

46

Apprendre le refactoring - l'art d' améliorer progressivement le code. Nous apprenons tous tout le temps, il est donc très courant de réaliser que le code que vous avez écrit vous-même pourrait être écrit d'une meilleure façon.

Mais vous devriez être capable de transformer le code existant pour appliquer ces améliorations sans avoir à partir de zéro.


4
Cette pratique vous aidera également à apprendre à écrire du code modulaire pouvant être refactorisé plus facilement. Toutes les conférences dans le monde ne m’ont pas appris cette habitude autant que de devoir diviser d’anciennes grandes fonctions en morceaux gérables pour que je n’aie pas à réécrire à partir de zéro. Chaque nouveau projet, je le fais mieux.
JKreft

Le meilleur point de départ à mon avis pour en savoir plus sur le refactoring est le suivant: Le refactoring concerne les nouvelles fonctionnalités
Wildcard

9

Si vous avez d’excellentes exigences statiques, que vous les comprenez bien et que vous avez le temps de faire une analyse détaillée, vous avez la possibilité de concevoir un bon design qui vous satisfera quand même.

Même dans ce cas heureux, vous pouvez apprendre de nouvelles fonctionnalités linguistiques qui auraient pu aider à créer un meilleur design.

Cependant, en général, vous n'aurez pas cette chance: les exigences seront moins que stellaires et incomplètes et, même si vous pensiez les comprendre, il s'avère que vous avez fait des hypothèses sur des points erronés.

Ensuite, les exigences changeront au fur et à mesure que les utilisateurs examineront vos livrables initiaux. Ensuite, quelque chose que les utilisateurs ne contrôlent pas va changer, par exemple le droit fiscal.

Tout ce que vous pouvez faire est de concevoir, en supposant que les choses vont changer. Refacturez-vous quand vous le pouvez, mais réalisez que le temps et le budget signifient souvent que votre livrable final n'est pas aussi élégant qu'il l'aurait été si vous saviez au début ce que vous savez maintenant.

Au fil du temps, vous pourrez mieux cerner les exigences que vous recevez et cerner les éléments de votre conception qui nécessiteront vraisemblablement une certaine flexibilité pour absorber les changements.

En fin de compte, acceptez le fait que le changement est constant et ignorez le pincement qui dit "J'aurais pu mieux le faire". Soyez fier et heureux d’avoir trouvé une solution.


Ou, autrement dit: apprenez à concevoir dès le départ pour plus de flexibilité , sans introduire de frais généraux inutiles. Idéalement, la flexibilité découle de la simplicité. Ensuite, votre conception a une chance de réussir le test de modification des exigences.
cmaster

3

Comment puis-je éviter de toujours avoir l'impression que si je reconstruisais complètement mon programme, je le ferais beaucoup mieux?

Ce que vous pourriez faire est de créer un prototype jetable avant de commencer à faire le "vrai" projet. Rapide et sale. Ensuite, lorsque vous obtenez un prototype pour prouver un concept, vous apprenez à connaître le système et à faire les choses correctement.

Mais ne soyez pas surpris si, après N années, vous revenez à ce code et pensez "quel gâchis".


3
Ou, si vous montrez le prototype à votre patron, il dit: «Brillant, ça ira. vous déplace sur un autre projet et votre prototype devient production.
RyanfaeScotland

2
Ce conseil est si commun qu'il existe un dicton à ce sujet. "Construisez-en un à jeter". Et ce conseil est tellement mal utilisé qu’il est dit: "Si vous en construisez un pour le jeter, vous en jetterez probablement deux."
Eric Lippert

2
@EricLippert Mon expérience a été terrible dans le sens opposé - si nous en construisons une à jeter, elle sera inévitablement expédiée au client.
Jon

2
@Jon: Oui, cela peut arriver, en particulier lorsque les erreurs de gestion "l'interface utilisateur a l'air de fonctionner" avec la présence de code. Cela dit, mon expérience a toujours été comme l'un de mes collègues me disait: "nous avons assez de temps pour construire deux fois de suite, mais pas assez de temps pour le faire correctement une fois". :-)
Eric Lippert

@EricLippert C'est exactement la raison pour laquelle l'interface graphique a été construite en dernier, et NON pour l'interface graphique d'un prototype;)
BЈовић

3

Rappelez-vous ce mantra:

Le parfait est l'ennemi du bien .

La solution parfaite n'est pas toujours la solution idéale . La solution idéale est celle qui atteint le statut "assez bon" avec le moins de travail possible.

  • Répond-il à toutes les exigences en termes de fonctionnalité et de performance?
  • Est-il exempt de bogues critiques que vous ne pouvez pas corriger dans l'architecture actuelle?
  • Estimez combien de travail vous allez investir dans la maintenance de cette application à l’avenir. L’effort de réécriture serait-il plus que l’effort à long terme qu’il permettrait d’économiser?
  • Y a-t-il une possibilité que votre nouveau design aggrave les choses?

Si vous répondez oui à toutes ces questions, alors votre logiciel est "assez bon" et il n'y a aucune bonne raison de le réécrire à partir de zéro. Appliquez les leçons de conception que vous avez apprises à votre prochain projet.

Il est parfaitement normal que chaque programmeur ait quelques programmes en désordre dans son passé. Il m'est arrivé plusieurs fois au cours de ma carrière de développeur de logiciels de regarder du code et de me demander "Quel imbécile a écrit ce gâchis?", Vérifié l'historique des versions et remarqué que c'était moi, il y a plusieurs années.


3

J'ai essayé de planifier les choses à l'avance, mais je n'arrive pas à tout prévoir avant de commencer à élaborer du code.

Il est tentant de penser qu'une planification parfaite vous donnera une conception / architecture de logiciel parfaite, mais il s'avère que c'est absolument faux. Cela pose deux gros problèmes. Premièrement, "sur le papier" et "le code" correspondent rarement, et la raison en est qu'il est facile de dire comment procéder, plutôt que de le faire . Deuxièmement, des changements imprévus dans les exigences deviennent apparents à un stade avancé du processus de développement et n’auraient pas pu être raisonnés dès le départ.

Avez-vous entendu parler du mouvement Agile? C'est une façon de penser où nous valorisons la "réaction au changement" par opposition au "suivi d'un plan" (entre autres). Voici le manifeste (c'est une lecture rapide). Vous pouvez également en savoir plus sur Big Design Up Front (BDUF) et sur les pièges à éviter.

Malheureusement, la version d'entreprise de "Agile" est un groupe de faux (maîtres scrum certifiés, processus lourd au nom de "Agile", forçant scrum, forçant une couverture de code à 100%, etc.) et aboutissant généralement à des modifications du processus pense Agile est un processus et une solution miracle (dont il n'est ni l'un ni l'autre). Lisez le manifeste agile, écoutez les personnes qui ont lancé ce mouvement, comme Oncle Bob et Martin Fowler, et ne vous laissez pas emporter par la version absurde de "l'entreprise Agile".

En particulier, vous pouvez généralement vous contenter de TDD (Test Driven Development) sur du code scientifique , et il y a de bonnes chances que votre projet logiciel devienne diablement bien. En effet, les codes scientifiques performants ont généralement des interfaces ultra-utilisables, la performance constituant une préoccupation secondaire (et parfois concurrente), ce qui vous permet de vous en sortir avec un design plus "gourmand". TDD oblige en quelque sorte votre logiciel à être ultra-utilisable , car vous écrivez comment vous voulez que les choses soient appelées (idéalement) avant de les implémenter réellement. Cela force également de petites fonctions avec de petites interfaces qui peuvent rapidement être appelées simplement, en "entrée" / "sortie", et vous met dans une bonne position pour refactoriser en cas de changement des exigences.

Je pense que nous pouvons tous convenir que le numpylogiciel de calcul scientifique est un succès. Leurs interfaces sont petites, super utilisables, et tout se joue bien ensemble. Notez que numpyle guide de référence recommande explicitement TDD: https://docs.scipy.org/doc/numpy-1.15.1/reference/testing.html . J'ai déjà utilisé TDD pour le logiciel d'imagerie RSO (Synthetic Aperature Radar): je peux également affirmer que cela fonctionne extrêmement bien pour ce domaine particulier.

Mise en garde: la partie conception de TDD fonctionne moins bien dans les systèmes où une refactorisation fondamentale (par exemple, décider que votre logiciel doit être hautement concurrentiel) serait difficile, comme dans un système distribué. Par exemple, si vous deviez concevoir quelque chose comme Facebook où vous avez des millions d'utilisateurs simultanés, utiliser TDD (pour piloter votre conception) serait une erreur ( vous pouvez toujours l'utiliser une fois que vous avez une conception préliminaire et que vous ne faites que "tester le premier développement". "). Il est important de réfléchir aux ressources et à la structure de votre application avant de vous lancer dans le code. TDD ne vous mènera jamais vers un système distribué hautement disponible.

Comment puis-je éviter de toujours avoir l'impression que si je reconstruisais complètement mon programme, je le ferais beaucoup mieux?

Compte tenu de ce qui précède, il devrait être assez évident qu'un design parfait est en fait impossible à réaliser. Il est donc difficile de rechercher un design parfait. Vous pouvez vraiment seulement vous approcher. Même si vous pensez pouvoir repenser à partir de zéro, il existe probablement encore des exigences cachées qui ne se sont pas manifestées. En outre, les réécritures prennent au moins le temps nécessaire au développement du code original. Ce ne sera presque certainement pas plus court, car il est probable que le nouveau design posera lui-même des problèmes imprévus. De plus, vous devrez ré-implémenter toutes les fonctionnalités de l'ancien système.

Une autre chose à considérer est que votre conception ne compte vraiment que lorsque les exigences changent .Peu importe à quel point la conception est mauvaise si rien ne change jamais (en supposant qu’elle soit entièrement fonctionnelle pour les cas d’utilisation actuels). J'ai travaillé sur une base comportant une instruction de commutation de 22 000 lignes (la fonction était encore plus longue). Était-ce un design terrible? Heck oui, c'était affreux. Avons-nous le réparer? Non, cela a bien fonctionné, et cette partie du système n'a jamais vraiment provoqué de crash ou de bugs. Cela n'a été touché qu'une fois au cours des deux années au cours desquelles j'ai participé au projet, et quelqu'un, vous l'avez deviné, a inséré un autre boîtier dans le commutateur. Mais cela ne vaut pas la peine de prendre le temps de réparer quelque chose qui est touché si rarement, ce n'est tout simplement pas le cas. Laissez la conception imparfaite telle qu'elle est, et si elle ne casse pas (ou se casse constamment), ne la corrigez pas. Alors peut-être que tu pourrais faire mieux ... mais est-ce que cela vaudrait la peine d'être réécrit? Qu'allez-vous gagner?

HTH.


2

Je suis tout à fait d'accord avec la réponse d'Andreas Kammerloher, mais je suis surpris que personne n'ait encore suggéré d'apprendre et d'appliquer certaines bonnes pratiques de codage. Bien sûr, il ne s’agit pas d’une solution miracle, mais l’utilisation d’une approche ouverte, de modèles de conception, la compréhension du moment où votre code sent le bon sens, etc. feront de vous un meilleur programmeur. Étudiez quelle est la meilleure utilisation des bibliothèques, des frameworks, etc. Il y en a bien plus, je ne fais que gratter la surface.

Cela ne signifie pas que vous ne considérerez pas votre ancien code comme un déchet total (vous verrez en fait les programmes les plus anciens encore plus déprimés que vous n'en auriez connaissance), mais chaque nouveau logiciel que vous écrivez vous le verrez. vous améliorez. Notez également que le nombre de meilleures pratiques de codage augmente avec le temps. Certaines changent simplement pour que vous n'atteigniez jamais la perfection. Accepter ceci ou tout à fait le chemin.

Une autre bonne chose est d'avoir une révision de code. Lorsque vous travaillez seul, il est facile de couper les coins ronds. Si une seconde personne révise votre code, elle pourra vous indiquer où vous ne suivez pas ces meilleures pratiques. De cette façon, vous produirez un meilleur code et vous apprendrez quelque chose.


1

Pour ajouter aux autres excellentes réponses ici, une chose que je trouve utile est de savoir où vous voulez aller .

Il est rare d'être autorisé à effectuer lui-même une refonte majeure. Mais vous pouvez souvent faire de plus petits travaux de refactorisation au fur et à mesure, «sous le radar», lorsque vous travaillez sur chaque zone de la base de code. Et si vous avez un objectif en tête, vous pouvez saisir ces occasions pour avancer, pas à pas, dans la bonne direction.

Cela peut prendre beaucoup de temps, mais la plupart des étapes vont améliorer le code et le résultat final en vaudra la peine.

De plus, avoir le sentiment de pouvoir faire mieux est un bon signe ! Cela montre que vous vous souciez de la qualité de votre travail et que vous l'évaluez de manière critique; donc vous apprenez et vous améliorez probablement. Ne laissez pas ces choses vous inquiéter, mais n'arrêtez pas de les faire!


1

Vous êtes tombé par inadvertance sur l'un des plus grands défis (aventures) de l'humanité, le pont entre l'homme et la machine. Le pont entre l'homme et la structure physique, le génie civil par exemple, est en construction depuis environ 200 ans ou plus.

Depuis que le développement de logiciels est devenu vraiment courant dans les années 90, il a environ 30 ans. Nous avons appris que ce n’est pas tant une discipline de l’ingénierie que des sciences sociales et nous ne faisons que commencer.

Oui, vous allez essayer TDD, Refactoring, Programmation fonctionnelle, Le modèle de référentiel, Event Sourcing, Quelque chose de MV, Script Java (<- Faites-le, c’est fou), Liaison de modèles, Aucun SQL, Conteneurs, Agile, SQL (<- faites ceci c'est puissant).

Il n'y a pas de solution unique. Même les experts sont encore à bout de force.

Bienvenue et soyez prévenu, c'est un endroit isolé; mais absolument fascinant.


1

Je vais aller un peu à contre-courant. C'est incroyablement commun , mais ce n'est pas acceptable . Cela indique que vous ne reconnaissez pas les bonnes manières d’organiser votre code lors de sa rédaction. Le sentiment vient du fait que votre code n’est pas simple .

Votre expérience a aussi été la mienne pendant longtemps, mais récemment (les deux dernières années), j'ai produit plus de code qui ne me donne pas l' impression que j'ai besoin de tout jeter. Voici à peu près ce que j'ai fait:

  1. Soyez clair sur les hypothèses retenues par un bloc de code particulier. Lancer des erreurs si elles ne sont pas remplies. Pensez-y de manière isolée , sans vous fier aux détails de ce que fait le reste du logiciel. (Ce que fait le reste du logiciel influence les hypothèses que vous appliquez et les cas d'utilisation que vous prenez en charge, mais n'influence pas le fait que vous jetiez une erreur lorsqu'une hypothèse est violée.)
  2. Arrêtez de croire que le respect des règles, des modèles et des pratiques produira un bon code. Jeter les mentalités et les pratiques qui ne sont pas évidentes et directes. Celui-ci était énorme. OO et TDD sont généralement enseignés d’une manière qui n’est pas fondée sur des considérations pratiques, c’est un ensemble de principes abstraits à suivre lors de l’écriture de code. Mais ceci est totalement inutile pour développer réellement un bon code. Si vous utilisez OO ou TDD, cela devrait être utilisé comme solution aux problèmes que vous comprenez avoir . En d'autres termes, ils ne devraient être utilisés que lorsque vous examinez un problème et que vous vous dites: "D'accord, cela est tout à fait logique et constitue une solution extrêmement évidente." Pas avant.
  3. Quand j'écris du code, concentrez-vous sur deux questions:
    • Est-ce que j'utilise des fonctionnalités et des bibliothèques telles qu'elles ont été conçues ? Cela inclut l’utiliser pour le type de problèmes qu’il était censé résoudre, ou du moins de problèmes très similaires.
    • Est-ce simple ? Mes collègues et moi-même serons-nous en mesure de suivre facilement cette logique plus tard? Y at-il des choses qui ne sont pas immédiatement évidentes dans le code?

Mon code est maintenant plus "procédural", c'est-à-dire qu'il est organisé en fonction de ses actions plutôt qu'en fonction des structures de données qu'il utilise. J'utilise des objets dans des langages où les fonctions autonomes ne peuvent pas être remplacées à la volée (C # et Java ne peuvent pas remplacer les fonctions à la volée, Python le peut). J'ai tendance à créer plus de fonctions utilitaires maintenant, ce qui éloigne simplement un passe-partout ennuyeux afin que je puisse réellement lire la logique de mon code. (Par exemple, lorsque j’avais besoin de traiter toutes les combinaisons d’éléments d’une liste, j’ai déplacé l’index en boucle vers une méthode d’extension qui renvoieTuples afin que la fonction d'origine ne soit pas encombrée de ces détails d'implémentation.) Je transmets beaucoup plus de paramètres en tant que paramètres à des fonctions, au lieu de laisser une fonction contacter un autre objet pour le récupérer. (L'appelant le récupère ou le crée et le transmet.) Je laisse maintenant plus de commentaires qui expliquent des choses qui ne sont pas évidentes juste en regardant le code , ce qui facilite le suivi de la logique d'une méthode. Je n'écris des tests que dans des cas limités où la logique de ce que je viens de faire m'inquiète et j'évite les simulacres. (Je fais plus de tests d'entrée / sortie sur des éléments isolés de la logique.) Le résultat est un code qui n'est pas parfait , mais qui semble en fait correct, même 2 ou 3 ans plus tard. C'est un code qui réagit assez bien pour changer; des choses mineures peuvent être ajoutées, supprimées ou modifiées sans que tout le système ne s'effondre.

Dans une certaine mesure, il faut traverser une période de désordre pour pouvoir avoir une certaine expérience. Mais si les choses sont encore tellement en désordre que vous voulez tout jeter et recommencer, quelque chose ne va pas; tu n'apprends pas.


0

En vous rappelant que votre temps est limité. Et votre temps futur est également limité. Que ce soit pour le travail ou les projets scolaires ou personnels, quand il s'agit de travailler avec du code, vous devez vous demander: "est-ce que la réécriture est la meilleure utilisation de mon temps limité et précieux?". Ou peut-être, "est-ce l' utilisation la plus responsable de mon temps limité"?

Parfois, la réponse sera sans équivoque oui . Généralement pas. Parfois, ce sera sur la clôture, et vous devrez utiliser votre discrétion. Parfois, c'est une bonne utilisation de votre temps simplement à cause des choses que vous apprendrez en les faisant.

J'ai beaucoup de projets, professionnels et personnels, qui pourraient bénéficier d'un port / réécriture. J'ai aussi d'autres choses à faire.


0

C'est une partie complètement normale de l'apprentissage. Vous réalisez des erreurs au fur et à mesure.

C'est comme ça que vous vous améliorez et ce n'est pas quelque chose que vous devriez vouloir éviter.


0

Vous pouvez vous faire l'expérience de savoir que l'envie séduisante de réécrire est généralement improductive. Trouvez un vieux projet open source velu, peu élégant, de complexité modérée. Essayez de le réécrire à partir de zéro et voyez comment vous le faites.

  • Votre conception à partir de zéro a-t-elle fini aussi élégante que vous l'espériez?
  • Votre solution est-elle vraiment au même problème? Quelles caractéristiques avez-vous omises? Quels cas de bord avez-vous manqués?
  • Quelles leçons durement gagnées dans le projet initial avez-vous effacées dans la poursuite de l'élégance?
  • Une fois que vous avez ajouté ces pièces manquantes à votre conception, est-il aussi propre qu’il l’était sans elles?

Finalement, votre instinct cessera de penser «je pourrais réécrire ce système tellement mieux» à penser «la cruauté de ce système peut indiquer une complexité qui n’est pas immédiatement apparente».

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.