Chapitre 1 · Leçon 2
Ouvert à l'extension, fermé à la modification
Section 1
Step 1
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
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.