Les Design Patterns structurels, en programmation, se concentrent sur la manière dont les classes et les objets sont structurés pour former des architectures logicielles plus flexibles et plus faciles à maintenir. Ils facilitent la composition d'objets pour créer des structures plus complexes tout en minimisant les dépendances entre les différents éléments du système.
Les design patterns comportementaux les plus utilisés sont les suivants :
Le design pattern Façade
Définition
Le design pattern Façade fournit une interface simplifiée à un ensemble de classes ou à un sous-système complexe.
Il agit comme une "façade" qui cache la complexité des interactions internes, offrant aux clients une interface plus simple et plus facile à utiliser.
Ce pattern est particulièrement utile lorsque vous avez un système complexe avec de nombreuses classes interconnectées, et que vous souhaitez fournir une interface plus intuitive pour les utilisateurs de ce système.
⚖️ Avantages et inconvénients
|
|
➕Avantages
- Simplification de l'interface : La façade offre une interface simplifiée et unifiée pour un ensemble de classes ou un sous-système, rendant le code plus facile à comprendre et à utiliser.
- Réduction de la dépendance : En utilisant une façade, les clients n'ont pas besoin de connaître les détails des classes internes du système. Cela réduit les dépendances entre les composants du système.
- Encapsulation : La façade masque la complexité du système et protège les composants internes des modifications, favorisant ainsi une meilleure encapsulation.
- Facilité de maintenance : Avec une interface simplifiée, il devient plus facile de modifier ou de mettre à jour le sous-système sans impacter les clients qui utilisent la façade.
➖Inconvénients
- Couche supplémentaire : L'utilisation d'une façade introduit une couche supplémentaire d'abstraction, ce qui peut parfois ajouter une légère surcharge en matière de performance et de complexité.
- Masquage excessif : Dans certains cas, la façade peut masquer trop de détails du sous-système, limitant ainsi la flexibilité et les possibilités d'optimisation pour les utilisateurs avancés.
Exemple d'implémentation
Dans mon précédent article sur le design pattern Décorateur, nous avons utilisé l'exemple du café. Ici nous utiliserons l'exemple d'une boutique d'une grande enseigne en vente de boisson caféinée.
Dans cette boutique, nous aurons plusieurs rôles d'employés, y compris le barista cuisinier, le serveur et le caissier. Nous allons créer une façade pour simplifier l'interface de ce système.
Sous système
La classe Barista
est responsable de la préparation des cafés, elle contient une méthode prepareCoffee
qui prend le nom d'un café en paramètre et simule la préparation de ce dernier.
public class Barista {
public void prepareCoffee(String coffee) {
System.out.println("Préparation du café: " + coffee);
}
}
La classe Waiter
est responsable de la prise de commande et du service des cafés. Elle contient deux méthodes : takeOrder
pour prendre une commande et serveCoffee
pour servir le plat au client.
public class Waiter {
public void takeOrder(String order) {
System.out.println("Prise de commande: " + order);
}
public void serveCoffee(String coffee) {
System.out.println("Service du café: " + coffee);
}
}
La classe Cashier
est responsable du traitement des paiements. Elle contient une méthode processPayment
qui prend une commande en paramètre et simule le traitement du paiement.
public class Cashier {
public void processPayment(String order) {
System.out.println("Traitement du paiement pour la commande: " + order);
}
}
Façade
La classe CoffeeShopFacade simplifie l'interaction avec les différents rôles des employés. Elle encapsule les instances de Barista
, Waiter
et Cashier
, et fournit une méthode completeOrder
qui orchestre les opérations nécessaires pour compléter une commande.
public class CoffeeShopFacade {
private Waiter waiter;
private Barista barista;
private Cashier cashier;
public CoffeeShopFacade() {
this.waiter = new Waiter();
this.barista = new Barista();
this.cashier = new Cashier();
}
public void completeOrder(String order) {
waiter.takeOrder(order);
barista.prepareCoffee(order);
waiter.serveCoffee(order);
cashier.processPayment(order);
}
}
Exemple d'utilisation
Dans notre classe Main
, nous créons une instance de CoffeeShopFacade
et utilisons la méthode completeOrder
pour passer une commande. Le client n'a pas besoin de connaître les détails des interactions entre les différents rôles.
public static void main(String[] args) {
CoffeeShopFacade coffeeShop = new CoffeeShopFacade();
coffeeShop.completeOrder("Cappucino");
}
L'exécution du code ci-dessus donnera le résultat suivant en console :
Prise de commande: Cappucino
Préparation du café: Cappucino
Service du café: Cappucino
Traitement du paiement pour la commande: Cappucino
En conclusion
Le design pattern Facade simplifie les interactions avec des systèmes complexes en offrant une interface simple. Bien qu'il ajoute une couche d'abstraction supplémentaire, les avantages en matière de simplification, réduction des dépendances et facilité de maintenance l'emportent souvent sur les inconvénients.
Si vous souhaitez approfondir le sujet, tout le code utilisé dans cet article est disponible juste ici !