Introduction
La structuration d'une application Go est un défi fréquemment rencontré par les développeurs, avec des opinions divergentes sur la meilleure approche. Dans cet article, nous explorerons différentes méthodes de structuration d'applications Go, en tirant des enseignements des experts du domaine.
La Structure à Plat
L'approche de la structure à plat consiste à regrouper tous les fichiers dans un seul package. Cela offre une simplicité initiale, facilitant l'apprentissage de l'application, mais peut conduire à des collisions de noms et des dépendances cycliques à mesure que l'application évolue.
my-flat-app
├── main.go
├── order.go
├── product.go
├── server.go
└── user.go
Points clés :
- Avantage initial de simplicité.
- Risque de collisions de noms et de dépendances cycliques à mesure que l'application grandit.
Modèle-Vue-Contrôleur par Couche
Cette approche organise les fichiers en packages nommés en fonction de leur fonctionnalité. Les fichiers sont répartis entre les packages de contrôleurs, modèles et vues.
my-mvc-by-layer-app
├── controllers
│ ├── order.go
│ ├── product.go
│ └── user.go
├── models
│ ├── order.go
│ ├── product.go
│ └── user.go
└── views
├── order.go
├── product.go
└── user.go
Points clés :
- Familiarité avec le modèle MVC.
- Attention aux dépendances cycliques avec une décomposition excessive.
Modèle-Vue-Contrôleur par Ressource
Cette variante organise les fichiers en packages nommés d'après les ressources qu'ils représentent.
my-mvc-by-resource-app
├── order
│ ├── controller.go
│ ├── model.go
│ └── view.go
├── product
│ ├── controller.go
│ ├── model.go
│ └── view.go
└── user
├── controller.go
├── model.go
└── view.go
Points clés :
- Moins courant, mais toujours considéré comme MVC.
- Structure basée sur les ressources de l'application.
Modèle-Vue-Contrôleur par Couche et Ressource
Cette approche complexe organise les fichiers en dossiers d'abord par couche, puis par ressource.
my-mvc-by-layer-and-resource-app
├── controllers
│ ├── order
│ │ └── controller.go
│ ├── product
│ │ └── controller.go
│ └── user
│ └── controller.go
├── models
│ ├── order
│ │ └── model.go
│ ├── product
│ │ └── model.go
│ └── user
│ └── model.go
└── views
├── order
│ └── view.go
├── product
│ └── view.go
└── user
└── view.go
Points clés :
- À éviter en raison des dépendances cycliques potentielles dans les modèles.
Conception Orientée Domaine
Cette approche, inspirée de la Conception Orientée Domaine (DDD), n'impose pas une structure prédéfinie. Les packages sont organisés en fonction des domaines d'application.
my-ddd-app
├── domain
├── github
├── gitlab
├── middleware
├── mock
├── server
└── sql
Points clés :
- DDD est axé sur l'évolution logicielle au fil du temps.
- Requiert une compréhension approfondie du domaine upfront.
Philosophie de Conception des Packages
Selon William Kennedy, les packages doivent fournir plutôt que contenir, être intuitifs, respecter les ressources et simplifier le code.
Principes :
- Packages doivent fournir, pas contenir.
- Usabilité et simplicité sont primordiales.
- Respect des ressources et performance.
- Réduction, minimisation et simplification du code.
Pratiques Recommandées par Ben Johnson
Ben Johnson préconise une approche où le package racine est réservé aux types de domaine, avec des sous-packages pour les dépendances, les mocks et l'injection de dépendances.
Structuration :
- Package racine pour les types de domaine.
- Sous-packages pour les dépendances, les mocks et l'injection de dépendances.
Conclusion
La structuration d'applications Go peut varier en fonction des besoins spécifiques du projet. Choisissez la structure qui convient le mieux à votre situation, en tenant compte de la taille de l'équipe, de l'expérience, de la vitesse de développement, et d'autres facteurs contextuels. Expérimentez avec différentes approches pour trouver celle qui optimise la clarté, la maintenabilité et l'évolutivité de votre code.