Introduction au DDD

Domain-Driven Design — vous le faites déjà depuis le mois 2

Bootcode IWA-S04 — Semaine 17, Jour 1

Objectifs de la leçon

1. Comprendre le DDD

Ce qu'est le Domain-Driven Design

2. L'Ubiquitous Language

Le même mot dans le code ET les conversations

3. Mapper S8-S16 → vocabulaire DDD

Repository, Use Case, Gateway, Mapper, DomainError

4. Pourquoi nommer en équipe

L'importance d'un vocabulaire partagé

Plan du cours

1

La révélation

Vous faites du DDD depuis S8 sans le savoir

2

Qu'est-ce que le DDD ?

Une façon de penser, pas un framework

3

L'Ubiquitous Language

Le même mot dans le code ET dans les discussions

4

Le tableau de correspondance

Ce que vous faites depuis S8 → vocabulaire DDD

5

Exercice oral

Les étudiants nomment eux-mêmes leurs patterns

Module 1

La révélation

Vous faites du DDD depuis S8 sans le savoir

Vous faites du DDD depuis S8

Rassurez-vous : aucune nouvelle façon de coder

Cette semaine, on ne va PAS apprendre de nouveaux patterns — juste du vocabulaire

📦

Repository

Depuis S8

⚙️

Use Case

Depuis S10

🚪

Gateway

Depuis S14

💡 Le DDD = nommer ce que vous faites déjà

Pas de nouveaux outils, pas de nouvelles bibliothèques — juste des mots

Module 2

Qu'est-ce que le DDD ?

Une façon de penser, pas un framework

DDD = une façon de penser

Le Domain-Driven Design n'est PAS un framework ni une bibliothèque

❌ Ce que le DDD n'est PAS

  • • Un package npm à installer
  • • Une nouvelle façon de coder
  • • Un framework comme Express
  • • Une recette toute faite

✅ Ce que le DDD EST

  • • Une approche de conception
  • • Un vocabulaire partagé
  • • Une façon de structurer la pensée
  • • Des patterns que vous utilisez déjà

💡 Le DDD donne des NOMS à vos patterns

Pour que toute l'équipe parle le même langage

Eric Evans & l'origine du DDD

Un peu d'histoire — mais en restant concret

📘 2003 — "Domain-Driven Design"

Eric Evans publie le livre fondateur du DDD

Il observe que les bonnes équipes partagent un vocabulaire commun entre code et métier

🎯 L'idée centrale

Le code doit refléter le langage réel du métier

Si le client dit "Article", le code dit "Article" — pas "Entity" ou "Record"

💡 On ne va pas lire Eric Evans aujourd'hui

On reste concret : votre code Bootcode est déjà du DDD en pratique

Module 3

L'Ubiquitous Language

Le même mot dans le code ET dans les conversations

Qu'est-ce que l'Ubiquitous Language ?

Définition

Un langage partagé entre les développeurs et le métier — le même vocabulaire partout

💬 Dans les conversations

"On crée un Article, on le sauve via le Repository"

💻 Dans le code

CreateArticle, ArticleRepository.save()

💡 "Ubiquitous" = présent partout

Le mot "Article" a le même sens dans le ticket, la réunion, et le fichier .ts

Exemple concret Bootcode

Les mêmes mots dans le code ET dans la conversation

// domain/usecases/RegisterStudent.ts

export class RegisterStudent {

constructor(private repo: StudentRepository) {}

async execute(input: { email: string }) {

const student = new Student(input);

await this.repo.save(student);

return student;

}

}

💬 Au stand-up

"J'ai créé un RegisterStudent qui sauve via le StudentRepository"

💻 Dans le code

RegisterStudent · StudentRepository

💡 Pas de traduction nécessaire entre code et discussion

C'est ça, l'Ubiquitous Language

Mauvais nommage vs Bon nommage

❌ Mauvais nommage

export class ProcessThing {

doStuff(data: any) { ... }

}

export class DataManager {

handle(x: any) { ... }

}

"Thing", "Stuff", "Data" — le métier ne dit jamais ça

✅ Bon nommage

export class RegisterStudent {

execute(input: StudentInput) { ... }

}

export class StudentRepository {

save(student: Student) { ... }

}

"Student", "Register" — le métier dit exactement ça

Module 4

Le tableau de correspondance

Ce que vous faites depuis S8 → vocabulaire DDD

Votre code = le vocabulaire DDD

Ce que vous faites

Votre fichier

Nom DDD

Sauver / lire en base

*Repository.ts

Repository

Orchestrer une action

*UseCase.ts

Use Case

Appeler un service externe

*Gateway.ts

Gateway

Convertir un format

*Mapper.ts

Mapper

Lever une erreur métier

*DomainError.ts

DomainError

💡 Vous connaissez déjà TOUT ce vocabulaire

Le DDD ne fait que donner des noms officiels à vos fichiers

📦 Ce que vous faites déjà : Repository

Le pattern que vous utilisez depuis la S8

// domain/repositories/StudentRepository.ts

export interface StudentRepository {

save(student: Student): Promise<void>;

findById(id: string): Promise<Student | null>;

}

// infra/repositories/PostgresStudentRepository.ts

export class PostgresStudentRepository implements StudentRepository {

async save(student: Student): Promise<void> {

// INSERT INTO students ...

}

}

💡 Repository = abstraire la persistance

Le domaine dit "sauve-moi ça", l'infra décide COMMENT (Postgres, fichier, mémoire)

⚙️ Use Case & 🚪 Gateway

L'orchestration et l'accès aux services externes

// domain/usecases/EnrollStudent.ts

export class EnrollStudent {

constructor(

private repo: StudentRepository,

private payment: PaymentGateway,

) {}

async execute(input: EnrollInput) {

const student = await this.repo.save(input.student);

await this.payment.charge(input.amount);

return student;

}

}

⚙️ Use Case

Orchestre la logique métier d'une action

🚪 Gateway

Abstrait un service externe (Stripe, API, etc.)

🔄 Mapper & ⚠️ DomainError

La conversion de formats et les erreurs métier

// infra/mappers/StudentMapper.ts

export class StudentMapper {

static toDomain(row: StudentRow): Student {

return new Student({ id: row.id, email: row.email });

}

}

// domain/errors/StudentNotFoundError.ts

export class StudentNotFoundError extends DomainError {

constructor(id: string) {

super("Student not found: " + id, 404);

}

}

🔄 Mapper

Convertit entre DB row et objet du domaine

⚠️ DomainError

Une erreur qui a du sens pour le métier

Module 5

Pourquoi nommer ?

L'importance du vocabulaire en équipe

L'importance du nommage en équipe

Un scénario concret : deux développeurs, deux vocabulaires

❌ Sans vocabulaire partagé

Dev A : "J'ai fini le DataManager"

Dev B : "C'est quoi ? Le ServiceHelper ?"

Dev A : "Non, celui qui sauve en base"

Dev B : "Ah, le StorageThing ?"

// 30 min perdues à clarifier

✅ Avec l'Ubiquitous Language

Dev A : "J'ai fini le StudentRepository"

Dev B : "Parfait, je l'injecte dans EnrollStudent"

// 0 min perdues — clair immédiatement

💡 Le bon nom = 0 friction de communication

Quand tout le monde dit "Repository", tout le monde comprend "Repository"

Pièges courants à éviter

❌ Penser que le DDD est une nouvelle façon de coder

✅ C'est du vocabulaire — vous codez déjà comme ça depuis S8

❌ Surcharger de théorie Eric Evans dès le début

✅ Rester concret avec votre propre code Bootcode

❌ Utiliser le jargon "bounded context" maintenant

✅ Les bounded contexts arrivent JEUDI — pas aujourd'hui

Exercice oral

À vous de jouer !

Nommez vous-mêmes les patterns que vous utilisez

1️⃣ Ouvrez votre projet Bootcode

Cherchez un fichier qui sauve ou lit en base

2️⃣ Dites à voix haute son nom DDD

"Ceci est un Repository parce que..."

3️⃣ Identifiez un Use Case et un Gateway

Expliquez pourquoi c'est ce pattern

4️⃣ Partagez avec le voisin

Utilisez le vocabulaire DDD dans votre explication

À retenir !

📚

DDD = du vocabulaire

Pas une nouvelle façon de coder

🗣️

Ubiquitous Language

Le même mot dans le code ET les discussions

🗺️

Vous faites déjà du DDD

Repository, Use Case, Gateway, Mapper, DomainError

👥

Le nommage = communication

Un bon nom = 0 friction en équipe

Questions ?

Ouvrez votre projet et nommez vos patterns à voix haute

Demain (J2) : Le pattern Repository en profondeur