Récap OOP : Mini-Jeu RPG

Classes, Encapsulation, Héritage, Composition en action

Construisons un système avec des classes qui collaborent

Objectifs de la leçon

1. Récapituler la semaine

Classes, encapsulation, héritage, composition

2. Concevoir un système

Plusieurs classes qui collaborent

3. Séparation des responsabilités

Appliquer sur un vrai projet

4. Bon design

Chaque classe a UN seul job

Plan du cours

1

Récap de la semaine

Classes, encapsulation (#), héritage, composition

2

Présentation du projet

Mini-jeu RPG avec des classes qui collaborent

3

Design du système

Personnage, Inventaire, Combat

4

GRAINE D'ARCHITECTURE

Combat ne modifie pas Personnage directement

5

Live coding

Construire le squelette ensemble

1️⃣ Les Classes

Le moule pour créer des objets

Une classe = propriétés + méthodes

Les objets sont des instances de cette classe

2️⃣ L'Encapsulation (#)

Protéger les données internes d'une classe

class Personnage {

#pointsDeVie = 100;

recevoirDegats(montant) {

this.pointsDeVie -= montant;

}

}

💡 On ne modifie jamais pointsDeVie directement → on passe par une méthode!

3️⃣ L'Héritage

Une classe enfant hérite des propriétés et méthodes du parent

class Guerrier extends Personnage {

#force = 10;

attaquer() {

return this.force;

}

}

Guerrier a automatiquement pointsDeVie et recevoirDegats()

4️⃣ La Composition

Une classe contient d'autres classes

"Un Personnage a un Inventaire" (pas "est un")

class Personnage {

#inventaire;

constructor() {

this.inventaire = new Inventaire();

}

}

💡 Composition vs Héritage : Privilégiez la composition!

Plus flexible, moins de couplage

🎮 Le Projet : Mini-Jeu RPG

Un jeu de combat en console

⚔️

Combat

Tour par tour

👤

Personnage

Héros & ennemis

🎒

Inventaire

Objets & potions

Les 3 Classes Principales

👤 Personnage

Gère l'état du héros

• Points de vie

• Force, défense

• Méthodes : attaquer(), recevoirDegats(), estVivant()

🎒 Inventaire

Gère les objets

• Liste d'objets

• Méthodes : ajouter(), utiliser(), aDesPotions()

⚔️ Combat

Orchestre le combat

• Gère les tours

• Méthodes : lancerTour(), determinerVainqueur()

👤 Design : Personnage

Responsabilité unique : Gérer l'état du héros

class Personnage {

#nom;

#pointsDeVie;

#force;

attaquer() {

return this.force;

}

recevoirDegats(montant) {

this.pointsDeVie -= montant;

}

estVivant() {

return this.pointsDeVie > 0;

}

}

✅ Toutes les propriétés sont privées (#) → encapsulation!

🎒 Design : Inventaire

Responsabilité unique : Gérer les objets

class Inventaire {

#objets = [];

ajouter(objet) {

this.objets.push(objet);

}

utiliser(objet) {

// Retirer l'objet de la liste

}

aDesPotions() {

return this.objets.includes('potion');

}

}

✅ L'inventaire ne sait pas ce qu'est un personnage → découplage!

⚔️ Design : Combat

Responsabilité unique : Orchestre le combat

class Combat {

#joueur;

#ennemi;

lancerTour() {

const degats = this.joueur.attaquer();

this.ennemi.recevoirDegats(degats);

}

determinerVainqueur() {

// Logique de fin de combat

}

}

🌱 GRAINE D'ARCHITECTURE

Le principe fondamental

Combat ne modifie PAS Personnage directement

Il appelle des méthodes → Séparation des responsabilités

❌ L'erreur à éviter

Combat accède directement aux propriétés privées

class Combat {

lancerTour() {

// ❌ INTERDIT!

this.ennemi.pointsDeVie -= 10;

}

}

⚠️ pointsDeVie est privé (#) → Combat ne peut pas y accéder!

C'est le test ultime de l'encapsulation

✅ La solution correcte

Combat appelle les méthodes de Personnage

class Combat {

lancerTour() {

const degats = this.joueur.attaquer();

this.ennemi.recevoirDegats(degats);

}

}

✅ Personnage contrôle comment ses données sont modifiées

C'est exactement le pattern Use Case + Aggregate

Pattern : Use Case + Aggregate

⚔️ Combat = Use Case

Orchestre le flux

• Gère les tours

• Coordonne les actions

• Ne contient pas de logique métier

👤 Personnage = Aggregate

Protège son état

• Encapsule ses données

• Expose des méthodes publiques

• Valide les invariants

✅ Ce pattern se retrouve partout dans les applications professionnelles!

🛠️ Live Coding

Construisons le squelette ensemble

Je construis la base, vous complétez

Chaque classe dans un fichier séparé

📁 Structure des fichiers

/src

├── Personnage.js

├── Inventaire.js

├── Combat.js

└── main.js // Point d'entrée

💡 Une classe = un fichier → organisation claire!

⚠️ Pièges courants

❌ Tout mettre dans une seule classe

"Pourquoi se compliquer? Une classe RPG suffit!"

✅ Guidez vers la séparation des responsabilités

❌ Combat accède aux propriétés privées

"Mais c'est plus simple de modifier pointsDeVie directement!"

✅ C'est le test ultime de l'encapsulation!

💡 Le projet semble ambitieux

Rassurez : on construit pas à pas!

✅ Commencez par Personnage, puis Inventaire, enfin Combat

🎯 Points clés à retenir

Chaque classe a UN seul job

Personnage = état | Inventaire = objets | Combat = orchestration

Combat ne touche PAS aux propriétés privées

Il appelle des méthodes → Personnage contrôle son état

Pattern Use Case + Aggregate

Use Case orchestre, Aggregate protège son état

Bon design = classes simples qui collaborent

Pas une classe géante qui fait tout!

📚 À retenir !

Encapsulation

Protéger les données avec private/protected

Séparation

Chaque classe a UN seul job

Collaboration

Les classes travaillent ensemble via des méthodes

Pattern

Use Case + Aggregate = architecture professionnelle

Un bon design émerge quand chaque classe a UN job

C'est la clé du code maintenable et évolutif!

🎯 Exercice pratique

Complétez le mini-jeu RPG

1. Créez la classe Personnage

Avec nom, pointsDeVie, force et les méthodes attaquer(), recevoirDegats(), estVivant()

2. Créez la classe Inventaire

Avec objets et les méthodes ajouter(), utiliser(), aDesPotions()

3. Créez la classe Combat

Avec lancerTour() qui appelle les méthodes de Personnage (pas d'accès direct aux propriétés!)

4. Testez dans main.js

Créez 2 personnages, lancez un combat, affichez le vainqueur

Questions?

L'OOP, c'est des classes simples qui collaborent

Pratiquez avec l'exercice RPG!

Encapsulation, Séparation, Collaboration → les piliers du bon design