Retour aux articles

Implémentation de la Clean Architecture dans une application Spring Boot

Implémentation de la Clean Architecture dans une application Spring Boot | Laty Gueye Samba - Développeur Full Stack Dakar Sénégal, Expert Java Spring Boot Angular

Implémentation de la Clean Architecture dans une application Spring Boot

Introduction

Cet article présente une méthode pratique pour appliquer la Clean Architecture dans une application Spring Boot. L'approche favorise la séparation des préoccupations, la testabilité et la maintenabilité. Les recommandations ci‑dessous visent à traduire les principes architecturaux en organisation de packages, contrats d'interfaces et exemples de code adaptés à l'écosystème Spring.

Principes essentiels

La Clean Architecture repose sur des couches concentriques et une règle simple : les dépendances pointent vers l'intérieur. Les couches typiques sont : Entities (domaine), Use Cases (cas d'utilisation), Interface Adapters (contrôleurs, presenters, gateways) et Frameworks & Drivers (Spring, base de données, UI). Chaque couche doit rester indépendante des détails d'implémentation externes.

Organisation des packages

Une organisation recommandée pour un projet Spring Boot :

com.example.app ├─ domain │ ├─ model │ └─ service (domain services) ├─ usecase ├─ adapter │ ├─ incoming (rest, graphql) │ └─ outgoing (persistence, external clients) └─ configuration

Cette structure permet de mapper directement les responsabilités et d'éviter les fuites de dépendances vers les frameworks.

Définir les entités et les ports (interfaces)

Les entités représentent le modèle métier sans dépendance à Spring. Les ports sont des interfaces qui exposent les capacités nécessaires pour les cas d'utilisation.

// Exemple d'entité package com.example.app.domain.model; public class Order { private Long id; private String status; // getters / setters / logique métier minimale } // Port (interface) pour la persistence package com.example.app.usecase.port; public interface OrderRepository { Order findById(Long id); Order save(Order order); }

Implémenter les cas d'utilisation

Les cas d'utilisation orchestrent la logique métier en s'appuyant uniquement sur des ports. Ils restent indépendants des frameworks.

package com.example.app.usecase; public class ProcessOrderUseCase { private final com.example.app.usecase.port.OrderRepository repo; public ProcessOrderUseCase(com.example.app.usecase.port.OrderRepository repo) { this.repo = repo; } public void execute(Long orderId) { Order order = repo.findById(orderId); // logique de traitement repo.save(order); } }

Adapters : contrôleurs et persistence

Les adapters implémentent les ports et traduisent les modèles entre couches. Dans Spring Boot, les contrôleurs REST et les repositories JPA se trouvent dans cette couche.

package com.example.app.adapter.out.persistence; @Repository public class OrderRepositoryJpa implements com.example.app.usecase.port.OrderRepository { // utilisation d'un Spring Data JPA interne ou EntityManager } package com.example.app.adapter.incoming.web; @RestController public class OrderController { private final com.example.app.usecase.ProcessOrderUseCase useCase; // endpoints exposés }

Configuration et injection de dépendances

La configuration Spring assemble les dépendances en liant les implémentations d'adapters aux ports définis par le domaine ou les cas d'utilisation. Les annotations @Configuration et @Bean ou l'injection par constructeur sont utilisées sans faire dépendre le domaine de Spring.

@Configuration public class UseCaseConfig { @Bean public ProcessOrderUseCase processOrderUseCase(OrderRepository orderRepository) { return new ProcessOrderUseCase(orderRepository); } }

Tests

La séparation claire permet d'écrire des tests unitaires pour les cas d'utilisation sans démarrer Spring. Les adapters peuvent être testés avec des tests d'intégration Spring Boot en isolant la couche d'infrastructure.

Bonnes pratiques et pièges à éviter

Quelques recommandations pratiques :

Séparer clairement les packages pour éviter les dépendances cycliques.

Utiliser des interfaces comme contrats entre couches et maintenir le domaine exempt de dépendances Spring.

Préserver la règle des dépendances : les détails (frameworks, DB) ne doivent jamais influencer les modèles du domaine.

Pièges courants : mélanger logique de présentation dans les cas d'utilisation, ou injecter des composants Spring directement dans les entités.

Conclusion

L'application des principes de la Clean Architecture dans un projet Spring Boot améliore la robustesse et facilite l'évolution. L'approche demande une discipline initiale dans la structuration du code et la définition des interfaces, mais apporte des bénéfices significatifs en testabilité et compréhension du système.

À propos de l'auteur

Laty Gueye Samba est développeur Full Stack basé à Dakar, Sénégal. Spécialiste des écosystèmes Java / Spring Boot et Angular.

Contact : latygueyesamba@gmail.com  |  Dakar, Sénégal