Principes SOLID en Go : théorie et pratique de A à Z

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Principes SOLID en Go : théorie et pratique de A à Z

\n\n

SOLID est l'acronyme de cinq principes fondamentaux de la programmation orientée objet qui aident à créer un code flexible, maintenable et évolutif. Bien que Go ne soit pas un langage OOP classique (il n'a pas de classes ni d'héritage au sens traditionnel), ces principes sont applicables et extrêmement utiles lors du développement en Go. Dans cet article, nous analyserons chaque principe avec des exemples concrets, montrerons comment les appliquer en Go et expliquerons pourquoi c'est important.

\n\n

1. Single Responsibility Principle (SRP) — Principe de responsabilité unique

\n\n

Essence : Chaque module, classe ou fonction ne doit avoir qu'une seule raison de changer. En d'autres termes, une entité doit être responsable d'une seule partie de la fonctionnalité.

\n\n

En Go, cela est souvent violé lorsqu'une structure (struct) effectue trop de tâches : travailler avec la base de données, envoyer des e-mails, générer des rapports.

\n\n

Mauvais exemple (violation du SRP) :

\n
type User struct {\n    Name  string\n    Email string\n}\n\nfunc (u *User) Save() error {\n    // logique de sauvegarde en BD\n    return nil\n}\n\nfunc (u *User) SendWelcomeEmail() error {\n    // logique d'envoi d'e-mail\n    return nil\n}\n\nfunc (u *User) GenerateReport() string {\n    // logique de génération de rapport\n    return "report"\n}\n
\n\n

Bon exemple (respect du SRP) :

\n
type User struct {\n    Name  string\n    Email string\n}\n\ntype UserRepository struct{}\n\nfunc (r *UserRepository) Save(u *User) error {\n    // seulement la sauvegarde\n    return nil\n}\n\ntype EmailService struct{}\n\nfunc (s *EmailService) SendWelcome(u *User) error {\n    // seulement l'envoi d'e-mail\n    return nil\n}\n\ntype ReportGenerator struct{}\n\nfunc (g *ReportGenerator) Generate(u *User) string {\n    // seulement la génération de rapport\n    return "report"\n}\n
\n\n

Conclusion : Chaque structure est responsable de sa propre tâche. Modifier la logique de sauvegarde n'affectera pas l'envoi d'e-mails.

\n\n

2. Open-Closed Principle (OCP) — Principe d'ouverture/fermeture

\n\n

Essence : Les entités logicielles (classes, modules, fonctions) doivent être ouvertes à l'extension, mais fermées à la modification. C'est-à-dire que vous devez pouvoir ajouter de nouvelles fonctionnalités sans modifier le code existant.

\n\n

En Go, cela se réalise parfaitement via les interfaces.

\n\n

Mauvais exemple (violation de l'OCP) :

\n
type PaymentProcessor struct{}\n\nfunc (p *PaymentProcessor) Process(paymentType string, amount float64) {\n    if paymentType == "credit_card" {\n        // logique pour carte de crédit\n    } else if paymentType == "paypal" {\n        // logique pour PayPal\n    }\n    // lors de l'ajout d'un nouveau type, il faudra modifier cette méthode\n}\n
\n\n

Bon exemple (respect de l'OCP) :

\n
type PaymentMethod interface {\n    Pay(amount float64) error\n}\n\ntype CreditCard struct{}\n\nfunc (c *CreditCard) Pay(amount float64) error {\n    // logique pour carte de crédit\n    return nil\n}\n\ntype PayPal struct{}\n\nfunc (p *PayPal) Pay(amount float64) error {\n    // logique pour PayPal\n    return nil\n}\n\nfunc ProcessPayment(method PaymentMethod, amount float64) error {\n    return method.Pay(amount)\n}\n
\n\n

Conclusion : Maintenant, pour ajouter un nouveau moyen de paiement (par exemple, ApplePay), il suffit de créer une nouvelle structure avec la méthode Pay(), sans toucher au code existant.

\n\n

3. Liskov Substitution Principle (LSP) — Principe de substitution de Barbara Liskov

\n\n

Essence : Les objets d'un programme doivent être remplaçables par des instances de leurs sous-types sans altérer la correction du programme. En Go, cela signifie que si une fonction accepte une interface, toute implémentation de cette interface doit fonctionner correctement, sans violer les attentes.

\n\n

Mauvais exemple (violation du LSP) :

\n
type Bird interface {\n    Fly() error\n}\n\nt                

Blogs

Book Recommendations