Patron Stratégie
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 69 sur 87.
Le pattern Strategy est un patron de conception comportemental qui vous permet de définir une famille d’algorithmes, d’encapsuler chacun d’eux dans sa propre classe et de les rendre interchangeables. Au lieu de coder en dur un comportement spécifique, vous pouvez remplacer les algorithmes à l’exécution sans modifier le code qui les utilise.
Imaginez un système de paiement qui prend en charge plusieurs méthodes de paiement. Sans le modèle Strategy, vous vous retrouveriez avec une logique conditionnelle désordonnée. Avec ce modèle, chaque méthode de paiement devient sa propre stratégie :
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " via Credit Card");
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " via PayPal");
}
}La classe context conserve une référence vers une stratégie et lui délègue le travail. L’essentiel est que le contexte ne sait pas quelle stratégie concrète il utilise. Il ne connaît que l’interface :
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}Vous pouvez maintenant modifier dynamiquement le comportement du paiement :
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100); // Payé 100 via carte de crédit
cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50); // Payé 50 via PayPalLe modèle Strategy est particulièrement utile lorsque vous disposez de plusieurs façons d’effectuer une action et que vous souhaitez passer facilement de l’une à l’autre. Ajouter un nouveau mode de paiement signifie simplement créer une nouvelle classe qui implémente PaymentStrategy : aucune modification du code existant n’est nécessaire.
Défi
FacileConstruisons un système de formatage de texte utilisant le pattern Strategy ! Vous allez créer un système dans lequel différentes stratégies de formatage peuvent être remplacées à l’exécution afin de transformer le texte de diverses manières, ce qui est idéal pour une application devant prendre en charge plusieurs formats de sortie.
Vous allez organiser votre code sur quatre fichiers :
TextFormatter.java: définissez l’interfaceTextFormatterque toutes les stratégies de formatage implémenteront. Elle doit déclarer une seule méthodeString format(String text)qui prend une chaîne et renvoie sa version formatée.Formatters.java: créez trois stratégies concrètes qui implémentent votre interfaceTextFormatter:UpperCaseFormatter- transforme le texte en lettres majuscules.LowerCaseFormatter- transforme le texte en lettres minuscules.TitleCaseFormatter- met en majuscule la première lettre de chaque mot tout en convertissant le reste en minuscules. Les mots sont séparés par des espaces.TextEditor.java: créez la classe de contexte qui utilise une stratégie de formatage. VotreTextEditordoit comporter :Un champ privé contenant la stratégie
TextFormatteractuelle.Une méthode
setFormatter(TextFormatter formatter)qui modifie la stratégie de formatage active.Une méthode
publishText(String text)qui applique le formateur actuel au texte et affichePublished: [formatted text]. Si aucun formateur n’a été défini, elle doit afficherPublished: [original text]sans modification.Main.java: assemblez votre système de stratégies ! Vous recevrez deux entrées : le texte à formater (String) et le style de formatage (String :"upper","lower"ou"title").Créez un
TextEditoret appelez d’abordpublishTextavec votre texte d’entrée avant de définir un formateur (pour illustrer le comportement par défaut).Ensuite, en fonction du style fourni, définissez la stratégie de formatage appropriée et appelez à nouveau
publishTextavec le même texte afin d’afficher le résultat formaté.
Vous recevrez deux entrées dans l’ordre suivant : le texte à formater (String) et le style de formatage (String).
Par exemple, avec les entrées hello world et title, votre sortie serait :
Published: hello world
Published: Hello WorldRemarquez que TextEditor ne connaît rien de la logique de formatage spécifique. Il délègue simplement le traitement à la stratégie actuellement définie. Il devient ainsi très facile d’ajouter de nouveaux styles de formatage sans modifier le code de l’éditeur !
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String text = scanner.nextLine();
String style = scanner.nextLine();
// TODO: Créer une instance de TextEditor
// TODO: Appeler publishText avec le texte d'entrée (avant de définir un formatter)
// TODO: En fonction de l'entrée de style ("upper", "lower", ou "title"),
// définir le formatter approprié et appeler publishText à nouveau
}
}Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron ItérateurEntraînez-vous par vous-même : Compilateur Java en ligne