Builders Academy
SOLID — Les 5 Principes de la Conception OO
2 of 3

Chapitre 1 · Leçon 2

Open/Closed Principle

Ouvert à l'extension, fermé à la modification

Section 1

Extension sans modification

Step 1

Le problème : modifier à chaque nouveau cas

OCP : une classe doit être ouverte à l'extension mais fermée à la modification. Si chaque nouveau type de paiement nécessite de modifier PaymentProcessor, on viole OCP.

snippet.typescript

typescript
1// ❌ Violation OCP
2class PaymentProcessor {
3  process(payment: Payment): void {
4    if (payment.type === 'WAVE') {
5      // Logique Wave
6    } else if (payment.type === 'ORANGE_MONEY') {
7      // Logique Orange Money
8    } else if (payment.type === 'CARD') {
9      // Logique carte bancaire
10    }
11    // Chaque nouveau moyen de paiement = modification de cette classe !
12  }
13}
14
15// ✅ Respect OCP — polymorphisme + injection
16interface PaymentGateway {
17  charge(amount: number, currency: string): Promise<PaymentResult>;
18}
19
20class WaveGateway implements PaymentGateway {
21  async charge(amount: number, currency: string): Promise<PaymentResult> {
22    return waveApi.initiatePayment({ amount, currency });
23  }
24}
25
26class OrangeMoneyGateway implements PaymentGateway {
27  async charge(amount: number, currency: string): Promise<PaymentResult> {
28    return orangeApi.requestPayment({ montant: amount, devise: currency });
29  }
30}
31
32class CardGateway implements PaymentGateway {
33  async charge(amount: number, currency: string): Promise<PaymentResult> {
34    return stripeApi.charges.create({ amount, currency });
35  }
36}
37
38// PaymentProcessor ne change plus quand on ajoute un gateway
39class PaymentProcessor {
40  constructor(private gateway: PaymentGateway) {}
41
42  async processOrder(order: Order): Promise<void> {
43    const result = await this.gateway.charge(order.total, order.currency);
44    if (!result.success) throw new PaymentError(result.message);
45  }
46}
47
48// Ajouter Paypal ? Créer PaypalGateway et l'injecter. Aucune modification existante.

snippet.typescript

typescript
1// ❌ Violation OCP
2class PaymentProcessor {
3  process(payment: Payment): void {
4    if (payment.type === 'WAVE') {
5      // Logique Wave
6    } else if (payment.type === 'ORANGE_MONEY') {
7      // Logique Orange Money
8    } else if (payment.type === 'CARD') {
9      // Logique carte bancaire
10    }
11    // Chaque nouveau moyen de paiement = modification de cette classe !
12  }
13}
14
15// ✅ Respect OCP — polymorphisme + injection
16interface PaymentGateway {
17  charge(amount: number, currency: string): Promise<PaymentResult>;
18}
19
20class WaveGateway implements PaymentGateway {
21  async charge(amount: number, currency: string): Promise<PaymentResult> {
22    return waveApi.initiatePayment({ amount, currency });
23  }
24}
25
26class OrangeMoneyGateway implements PaymentGateway {
27  async charge(amount: number, currency: string): Promise<PaymentResult> {
28    return orangeApi.requestPayment({ montant: amount, devise: currency });
29  }
30}
31
32class CardGateway implements PaymentGateway {
33  async charge(amount: number, currency: string): Promise<PaymentResult> {
34    return stripeApi.charges.create({ amount, currency });
35  }
36}
37
38// PaymentProcessor ne change plus quand on ajoute un gateway
39class PaymentProcessor {
40  constructor(private gateway: PaymentGateway) {}
41
42  async processOrder(order: Order): Promise<void> {
43    const result = await this.gateway.charge(order.total, order.currency);
44    if (!result.success) throw new PaymentError(result.message);
45  }
46}
47
48// Ajouter Paypal ? Créer PaypalGateway et l'injecter. Aucune modification existante.

Topics and skills covered

  • SOLID
  • OCP
  • Extension
  • Polymorphisme