Bonjour,
Dans l’article précédent, nous avons exploré la théorie du Builder pattern.
Voyons un exemple plus concret :
Supposons que nous construisons le modèle de base d’un jeu de rôle (RPG). Voici les règles de base :
- Un joueur peut être un Héros : un Guerrier, un Mage, ou un Voleur (on garde ça simple)
- Chaque Héros a 4 caractéristiques principales : Santé, Force, Esprit et Vitesse, comptées en points.
- Les Héros ont un Niveau, et les caractéristiques de départ sont basées sur ce niveau (Santé commence à Niveau * 10, Force et Esprit commencent à Niveau * 5, et Vitesse commence à Niveau * 3)
- Le Guerrier a un Modificateur (+2 Force, -2 Esprit), le Mage a un Modificateur (+2 Esprit, -2 Force)
- Le joueur peut améliorer 2 Caractéristiques de 1 point chacune ou 1 caractéristique de 2 points, afin de personnaliser son Héros.
Une implémentation naïve de la classe Hero serait :
| |
Concentrons-nous sur la Création du Héros : Tous les Héros sont du même type : En effet, malgré les différentes classes, chaque Héros a le même type de caractéristiques. Donc, il n’y a pas besoin d’une classe spécifique reflétant la “Classe du Héros”.
Voici un premier test (Notez que j’utilise le framework de test Fixie et la bibliothèque d’assertions Shouldly, je posterai à ce sujet bientôt) :
| |
Nous voulons nous assurer que notre builder peut construire un guerrier. Donc l’implémentation est directe :
| |
Évidemment, nous pouvons ajouter les méthodes pour les autres classes (gardez à l’esprit que le périmètre est vraiment restreint). L’étape suivante serait de s’assurer que nous ne pouvons pas construire un Héros sans classe. Le test serait :
| |
Donc nous mettons à jour le Builder en conséquence :
| |
La garde se produit dans la méthode Create car c’est l’endroit le plus pratique pour la placer, pour le moment.
En suivant nos “Règles Métier”, nous aboutissons à ce type de classe :
| |
Nous avons en fait construit un Domain-Specific-Language (DSL) pour notre contexte de Création de Héros. Cela peut sembler un peu complexe pour l’objectif à première vue, mais nous avons atteint une séparation complète entre la complexité de construire un Héros et le comportement du Héros plus tard dans le jeu. Pour illustrer cela, nous pouvons regarder une implémentation potentielle d’un client de jeu :
| |
Dans cet article, nous avons vu comment implémenter le Builder Design Pattern en C# avec une approche Fluent Interface.
Vous pouvez trouver le code source dans ce repository github

Commentaires
💬 Les commentaires sont partagés entre toutes les versions linguistiques de cet article.