Java 21 introduit le filtrage par motif pour les instructions switch, une fonctionnalité qui peut considérablement réduire le code standard dans les conceptions orientées domaine. Elle permet une gestion plus expressive et concise des structures d'objets complexes, rendant votre code plus facile à lire et à maintenir. Cet article explore comment tirer parti de cette fonctionnalité dans des contextes DDD, avec des exemples pratiques et des meilleures pratiques.
L'Ancienne Méthode : Un Voyage Nostalgique dans le Passé
Avant de plonger dans les nouveautés, rappelons-nous pourquoi nous avions besoin de cette mise à jour. Imaginez ceci : vous travaillez sur une plateforme de commerce électronique avec un système de traitement des commandes complexe. Votre modèle de domaine inclut divers états de commande, chacun nécessitant un traitement différent. Votre code pourrait ressembler à ceci :
public void processOrder(Order order) {
if (order instanceof NewOrder) {
handleNewOrder((NewOrder) order);
} else if (order instanceof ProcessingOrder) {
handleProcessingOrder((ProcessingOrder) order);
} else if (order instanceof ShippedOrder) {
handleShippedOrder((ShippedOrder) order);
} else if (order instanceof CancelledOrder) {
handleCancelledOrder((CancelledOrder) order);
} else {
throw new IllegalStateException("Unknown order state");
}
}
Pas vraiment agréable à regarder, n'est-ce pas ? Cette approche est verbeuse, sujette aux erreurs et franchement, un peu ennuyeuse. Entrez le filtrage par motif pour switch, scène à gauche.
La Nouvelle Tendance : Filtrage par Motif pour Switch
Le filtrage par motif pour switch de Java 21 nous permet de réécrire le code ci-dessus de manière beaucoup plus élégante :
public void processOrder(Order order) {
switch (order) {
case NewOrder n -> handleNewOrder(n);
case ProcessingOrder p -> handleProcessingOrder(p);
case ShippedOrder s -> handleShippedOrder(s);
case CancelledOrder c -> handleCancelledOrder(c);
default -> throw new IllegalStateException("Unknown order state");
}
}
Voilà ce que j'appelle une amélioration ! Mais attendez, il y a plus. Voyons pourquoi c'est si important pour le DDD.
Pourquoi les Passionnés de DDD Devraient s'Intéresser
- Expressivité : Le filtrage par motif permet à votre code de mieux s'aligner avec le langage de votre domaine.
- Réduction de la Charge Cognitive : Moins de code standard signifie que votre cerveau peut se concentrer sur la logique métier, pas sur la syntaxe.
- Sécurité de Type : Le compilateur s'assure que vous gérez tous les cas possibles, réduisant les erreurs à l'exécution.
- Extensibilité : Ajouter de nouveaux états ou types devient un jeu d'enfant, favorisant des conceptions évolutives.
Exemple Réel : Dompter la Bête du Traitement des Commandes
Développons notre exemple de traitement des commandes pour montrer comment le filtrage par motif peut gérer des scénarios plus complexes. Imaginons que nous voulons appliquer différents rabais en fonction du type et du statut de la commande :
public BigDecimal calculateDiscount(Order order) {
return switch (order) {
case NewOrder n when n.getTotal().compareTo(BigDecimal.valueOf(1000)) > 0 ->
n.getTotal().multiply(BigDecimal.valueOf(0.1));
case ProcessingOrder p when p.isExpedited() ->
p.getTotal().multiply(BigDecimal.valueOf(0.05));
case ShippedOrder s when s.getDeliveryDate().isBefore(LocalDate.now().plusDays(2)) ->
s.getTotal().multiply(BigDecimal.valueOf(0.02));
case CancelledOrder c when c.getRefundStatus() == RefundStatus.PENDING ->
c.getTotal().multiply(BigDecimal.valueOf(0.01));
default -> BigDecimal.ZERO;
};
}
Ce fragment de code montre comment le filtrage par motif peut gérer avec élégance des règles métier complexes. Nous appliquons différents calculs de rabais basés non seulement sur le type de commande, mais aussi sur des conditions spécifiques à chaque type.
Améliorer les Événements de Domaine avec le Filtrage par Motif
Les événements de domaine sont une partie cruciale du DDD. Voyons comment le filtrage par motif peut simplifier la gestion des événements :
public void handleOrderEvent(OrderEvent event) {
switch (event) {
case OrderPlacedEvent e -> {
notifyWarehouse(e.getOrder());
updateInventory(e.getOrder().getItems());
}
case OrderShippedEvent e -> {
notifyCustomer(e.getOrder(), e.getTrackingNumber());
updateOrderStatus(e.getOrder(), OrderStatus.SHIPPED);
}
case OrderCancelledEvent e -> {
refundCustomer(e.getOrder());
restoreInventory(e.getOrder().getItems());
}
default -> throw new IllegalArgumentException("Unknown event type");
}
}
Cette approche permet une séparation claire des préoccupations et facilite l'ajout de nouveaux types d'événements à mesure que votre modèle de domaine évolue.
Pièges Potentiels : Ce n'est pas Toujours Rose
Avant de réécrire l'intégralité de votre code, parlons de quelques inconvénients potentiels :
- Surutilisation : Tout n'a pas besoin d'être une expression switch. Parfois, un simple if-else est plus lisible.
- Complexité Croissante : Il est tentant d'ajouter de plus en plus de cas, ce qui peut conduire à des instructions switch surchargées.
- Performance : Pour un petit nombre de cas, un if-else traditionnel peut être légèrement plus rapide (bien que la différence soit généralement négligeable).
Meilleures Pratiques pour le Filtrage par Motif en DDD
- S'Aligner avec le Langage Ubiquitaire : Utilisez le filtrage par motif pour que votre code ressemble davantage à la façon dont vos experts de domaine parlent.
- Rester Concentré : Chaque cas doit gérer un scénario spécifique dans votre domaine.
- Combiner avec des Méthodes de Fabrique : Utilisez le filtrage par motif dans les méthodes de fabrique pour créer des objets de domaine basés sur des critères complexes.
- Refactoriser Graduellement : Ne vous sentez pas obligé de tout réécrire d'un coup. Commencez par les parties les plus complexes et lourdes en code standard de votre base de code.
L'Avenir est Prometteur (et Moins Verbeux)
Le filtrage par motif pour switch dans Java 21 est plus qu'un simple sucre syntaxique – c'est un outil puissant pour exprimer une logique de domaine complexe de manière claire et concise. En réduisant le code standard et en permettant un code plus expressif, il permet aux développeurs de se concentrer sur ce qui compte vraiment : traduire les exigences métier en code propre et maintenable.
Alors que nous continuons à repousser les limites de ce qui est possible dans la conception orientée domaine, des fonctionnalités comme celle-ci nous rappellent que parfois, moins c'est vraiment plus. Alors allez-y, refactorisez ces chaînes if-else compliquées et adoptez l'élégance du filtrage par motif. Votre futur vous (et vos relecteurs de code) vous en remercieront.
"La simplicité est la sophistication ultime." - Léonard de Vinci
(Il parlait peut-être d'art, mais j'aime à penser qu'il apprécierait aussi une expression switch bien conçue.)
Pour Aller Plus Loin
- JEP 441 : Filtrage par motif pour switch
- Spring Framework GitHub (pour des exemples de DDD en action)
- Martin Fowler sur la Conception Orientée Domaine
Maintenant, si vous voulez bien m'excuser, j'ai quelques instructions switch à refactoriser. Bon codage !