Patron Monteur
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 67 sur 87.
Le Patron Builder est un patron de conception de création qui résout un problème courant : la construction d'objets complexes comportant de nombreux paramètres optionnels. Au lieu de créer plusieurs constructeurs ou de passer null pour les paramètres inutilisés, le Builder vous permet de construire des objets étape par étape.
Envisagez de créer un objet User avec des champs obligatoires (nom, e-mail) et des champs facultatifs (âge, téléphone, adresse). Sans un Builder, vous auriez besoin de constructeurs télescopiques ou d'un constructeur complexe avec de nombreux paramètres. Le pattern Builder offre une approche plus propre :
public class User {
private final String name; // requis
private final String email; // requis
private final int age; // optionnel
private final String phone; // optionnel
private User(UserBuilder builder) {
this.name = builder.name;
this.email = builder.email;
this.age = builder.age;
this.phone = builder.phone;
}
public static class UserBuilder {
private final String name;
private final String email;
private int age;
private String phone;
public UserBuilder(String name, String email) {
this.name = name;
this.email = email;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return new User(this);
}
}
}Les méthodes du Builder retournent this, permettant le chaînage de méthodes — une manière fluide et lisible de construire des objets :
User user = new User.UserBuilder("Alice", "alice@email.com")
.age(25)
.phone("555-1234")
.build();Remarquez comment le constructeur User est privé — les objets ne peuvent être créés que via le Builder. Ce pattern excelle lorsque les objets ont de nombreux champs optionnels, rendant votre code plus lisible et moins sujet aux erreurs que les longues listes de paramètres.
Défi
FacileConstruisons un système de commande de pizza en utilisant le Builder Pattern ! Au lieu de gérer un constructeur qui prend des dizaines de paramètres pour toutes les garnitures et options possibles, vous allez créer un builder fluide qui rend la personnalisation de la pizza propre et lisible.
Vous organiserez votre code sur deux fichiers :
Pizza.java: Créez une classePizzaqui utilise le Builder Pattern pour la construction. Votre pizza doit avoir les champs suivants :size(String) - requis, représente la taille de la pizzacheese(boolean) - optionnel, par défaut à falsepepperoni(boolean) - optionnel, par défaut à falsemushrooms(boolean) - optionnel, par défaut à falseLe constructeur de
Pizzadoit être privé et n'accepter qu'unPizzaBuildercomme paramètre, en copiant toutes les valeurs du builder vers les champs de la pizza.Incluez une méthode
getDescription()qui retourne une chaîne de caractères dans ce format :[size] Pizza with: [toppings]où toppings est une liste séparée par des virgules des garnitures qui sont à true (Cheese, Pepperoni, Mushrooms). Si aucune garniture n'est sélectionnée, la partie toppings doit simplement indiquerno toppings.Créez une classe interne statique
PizzaBuilderavec :- Un constructeur qui prend le paramètre requis
size - Des méthodes
cheese(),pepperoni(), etmushrooms()qui mettent chacune leur booléen respectif à true et retournentthispour le chaînage - Une méthode
build()qui retourne une nouvellePizza
- Un constructeur qui prend le paramètre requis
Main.java: Démontrez votre builder de pizza en action ! Vous recevrez quatre entrées : la taille de la pizza (String), et trois valeurs yes/no (Strings) indiquant s'il faut ajouter du fromage, du pepperoni et des champignons respectivement.Créez un
PizzaBuilderavec la taille donnée. Ensuite, en fonction de chaque entrée yes/no, chaînez les méthodes de garniture appropriées. Si l'entrée est"yes", appelez cette méthode de garniture ; si c'est"no", ignorez-la. Enfin, appelezbuild()pour créer votre pizza.Affichez le résultat de l'appel à
getDescription()sur votre pizza terminée.
Vous recevrez quatre entrées dans l'ordre : size (String), add cheese (String : "yes" ou "no"), add pepperoni (String : "yes" ou "no"), add mushrooms (String : "yes" ou "no").
Par exemple, avec les entrées Large, yes, no, yes, votre sortie serait : Large Pizza with: Cheese, Mushrooms
Remarquez comment le Builder Pattern vous permet de construire des pizzas avec n'importe quelle combinaison de garnitures sans avoir besoin de constructeurs séparés pour chaque possibilité !
Aide-mémoire
Le Builder Pattern (ou patron de conception Monteur) est un patron de conception de création utilisé pour construire des objets complexes comportant de nombreux paramètres optionnels. Il permet d'éviter les constructeurs télescopiques et les longues listes de paramètres en construisant les objets étape par étape.
Structure
Le patron se compose de :
- Une classe avec un constructeur privé qui n'accepte qu'un builder
- Une classe interne statique Builder qui construit l'objet
- Des méthodes de builder qui retournent
thispour le chaînage de méthodes - Une méthode
build()qui crée l'objet final
Exemple d'implémentation
public class User {
private final String name; // requis
private final String email; // requis
private final int age; // optionnel
private final String phone; // optionnel
private User(UserBuilder builder) {
this.name = builder.name;
this.email = builder.email;
this.age = builder.age;
this.phone = builder.phone;
}
public static class UserBuilder {
private final String name;
private final String email;
private int age;
private String phone;
public UserBuilder(String name, String email) {
this.name = name;
this.email = email;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public User build() {
return new User(this);
}
}
}Utilisation avec le chaînage de méthodes
User user = new User.UserBuilder("Alice", "alice@email.com")
.age(25)
.phone("555-1234")
.build();Le patron Builder est idéal lorsque les objets possèdent de nombreux champs optionnels, offrant un code lisible et facile à maintenir par rapport aux constructeurs avec de nombreux paramètres.
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lire les entrées
String size = scanner.nextLine();
String addCheese = scanner.nextLine();
String addPepperoni = scanner.nextLine();
String addMushrooms = scanner.nextLine();
// TODO : Créer un PizzaBuilder avec la taille donnée
// TODO : Enchaîner les méthodes de garniture basées sur les entrées oui/non
// TODO : Construire la pizza et afficher sa description
}
}
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érateur