
J'ai trouvé sur GitHub le projet PythonPlantsVsZombies. C'est un clone du légendaire « Plants vs. Zombies » en Pygame : avec animations, différents types de zombies et niveaux via JSON. Mais dès qu'on regarde sous le capot, on commence à plaindre les zombies. Au moins, eux n'ont pas à maintenir ce code.
Disséquons ce chef-d'œuvre d'ingénierie.
1️⃣ L'enfer des
if-elif ou « L'usine sur béquilles »Dans le fichier
source/state/level.py se trouve la méthode addPlant. Quand vous plantez une plante sur une case, le moteur lance un interrogatoire de 19 branches elif. « Tu es un tournesol ? Non ? Et peut-être un pois-tireur ? Toujours pas ? Alors, peut-être une cerise ? »
if self.plant_name == c.SUNFLOWER:
new_plant = plant.SunFlower(x, y, self.sun_group)
elif self.plant_name == c.PEASHOOTER:
new_plant = plant.PeaShooter(x, y, self.bullet_groups[map_y])
# ... et ainsi de suite 17 foisVous voulez ajouter un nouveau type de tournesol ? Allez au milieu du fichier et ajoutez un autre :
elif self.plant_name == c.SUNSHROOM:
new_plant = plant.SunShroom(x, y, self.sun_group)C'est un anti-patron classique. Dans un monde normal, on utilise un registre de classes ou un mapping. Un dictionnaire, et cette honte se transforme en deux lignes élégantes.
2️⃣ Synchronisation de listes — le chemin vers la schizophrénie
Dans
source/component/menubar.py, les données sur les plantes (noms, coût, temps de recharge) sont dispersées dans quatre listes indépendantes. Toutes doivent être strictement de la même longueur et dans un ordre strict.
Erreur d'un index dans plant_sun_list ? Félicitations, maintenant votre pois-tireur coûte comme une cerise, et la cerise est gratuite.
Nous avons des
dataclasses, des dictionnaires, de la POO, enfin. Regroupez les données liées dans des objets, sinon le débogage deviendra un enfer.3️⃣ Effets secondaires globaux.
Dans
source/tool.py, l'initialisation de Pygame et la création de la fenêtre (SCREEN) se font directement au niveau du module. Quel est le problème : Vous ne pouvez pas simplement importer une constante ou une fonction auxiliaire de ce fichier dans des tests sans initialiser tout le noyau graphique. Cela tue la possibilité de tests unitaires. La logique doit être séparée du « matériel ».
4️⃣ Un « cerveau » intelligent pour des objets stupides
Au lieu d'utiliser le polymorphisme (où chaque plante sait elle-même comment attaquer), la classe principale
Level vérifie manuellement les noms des chaînes : if plant.name == c.THREEPEASHOOTER, et décide elle-même où tirer. Cela rend les classes de plantes de simples décorations avec des images, et la logique du jeu un monolithe insoutenable.Verdict :
Le projet est cool comme démo et pour tâter Pygame. Mais si vous arrivez avec une telle approche architecturale sur un projet normal — vous serez dévorés plus vite que les zombies ne dévorent un noyer sur la première ligne.
🎓 Ce qu'on apprend :
1. Ne faites pas de gigantesques chaînes
if-else là où le polymorphisme fonctionne.2. Regroupez les données liées dans des objets ou des dictionnaires.
3. Si dans votre code il y a la phrase « l'indice dans cette liste correspond à l'indice dans cette autre liste » — supprimez tout et réécrivez.
4. Les ressources (graphiques/son) doivent être chargées paresseusement (Lazy Loading), pas « tout et tout de suite » à l'import du module.
#on_crame_le_code
Комментарии
0Комментариев пока нет.