Le modèle Builder pour la construction d'objets complexes en Java

Introduction au pattern Builder

Le pattern Builder permet de construire des objets complexes de manière incrémentale, en séparant la logique de construction de la représentation. Il est idéal lorsque la création d'un objet implique de nombreuses validations, conversions ou attributs interdépendants.

Scénarios typiques d'utilisation

Dans des domaines comme le commerce électronique, des entités telles que les produits, les bons de commande ou les docmuents de stock sont souvent composées de multiples champs. Le pattern Builder encapsule la construction, la rendant modulbale et facile à maintenir.

Exemple avec un Directeur

Cette approche utilise un Directeur pour orchestrer la construction via une interface Builder, garantissant une séparation claire des responsabilités.

package com.example.patterns;

public class ConstructionAvecDirecteur {
    public static void main(String[] args) {
        Constructeur constructeur = new ConstructeurConcret();
        Directeur directeur = new Directeur(constructeur);
        ObjetComplexe objet = directeur.construire("alpha", "beta", "gamma");
        System.out.println(objet);
    }

    interface Constructeur {
        void definirAttribut1(String val);
        void definirAttribut2(String val);
        void definirAttribut3(String val);
        ObjetComplexe obtenirResultat();
    }

    static class Directeur {
        private final Constructeur constructeur;

        Directeur(Constructeur constructeur) {
            this.constructeur = constructeur;
        }

        ObjetComplexe construire(String val1, String val2, String val3) {
            constructeur.definirAttribut1(val1);
            constructeur.definirAttribut2(val2);
            constructeur.definirAttribut3(val3);
            return constructeur.obtenirResultat();
        }
    }

    static class ConstructeurConcret implements Constructeur {
        private final ObjetComplexe objet = new ObjetComplexe();

        @Override
        public void definirAttribut1(String val) {
            objet.setPremier(val);
        }

        @Override
        public void definirAttribut2(String val) {
            objet.setDeuxieme(val);
        }

        @Override
        public void definirAttribut3(String val) {
            objet.setTroisieme(val);
        }

        @Override
        public ObjetComplexe obtenirResultat() {
            return objet;
        }
    }

    static class ObjetComplexe {
        private String premier;
        private String deuxieme;
        private String troisieme;

        public String getPremier() { return premier; }
        public void setPremier(String val) { this.premier = val; }
        public String getDeuxieme() { return deuxieme; }
        public void setDeuxieme(String val) { this.deuxieme = val; }
        public String getTroisieme() { return troisieme; }
        public void setTroisieme(String val) { this.troisieme = val; }

        @Override
        public String toString() {
            return "ObjetComplexe{premier='" + premier + "', deuxieme='" + deuxieme + "', troisieme='" + troisieme + "'}";
        }
    }
}

Exemple avec appel en chaîne

Ici, le Builder retourne une référence à lui-même après chaque méthode, permettant une syntaxe fluide et éliminant le besoin d'un Directeur explicite.

package com.example.patterns;

public class ConstructionFluente {
    public static void main(String[] args) {
        Constructeur builder = new ConstructeurConcret();
        ObjetComplexe objet = builder
                .avecAttribut1("delta")
                .avecAttribut2("epsilon")
                .avecAttribut3("zeta")
                .construire();
        System.out.println(objet);
    }

    interface Constructeur {
        Constructeur avecAttribut1(String val);
        Constructeur avecAttribut2(String val);
        Constructeur avecAttribut3(String val);
        ObjetComplexe construire();
    }

    static class ConstructeurConcret implements Constructeur {
        private final ObjetComplexe objet = new ObjetComplexe();

        @Override
        public Constructeur avecAttribut1(String val) {
            objet.setUn(val);
            return this;
        }

        @Override
        public Constructeur avecAttribut2(String val) {
            objet.setDeux(val);
            return this;
        }

        @Override
        public Constructeur avecAttribut3(String val) {
            objet.setTrois(val);
            return this;
        }

        @Override
        public ObjetComplexe construire() {
            return objet;
        }
    }

    static class ObjetComplexe {
        private String un;
        private String deux;
        private String trois;

        public String getUn() { return un; }
        public void setUn(String val) { this.un = val; }
        public String getDeux() { return deux; }
        public void setDeux(String val) { this.deux = val; }
        public String getTrois() { return trois; }
        public void setTrois(String val) { this.trois = val; }

        @Override
        public String toString() {
            return "ObjetComplexe{un='" + un + "', deux='" + deux + "', trois='" + trois + "'}";
        }
    }
}

Avantages du pattern Builder

  • Améliore la clarté du code en décomposant la construction en étapes gérables.
  • Facilite la maintenance et l'extension grâce à l'abstraction entre le Directeur et le Builder.
  • Offre flexibilité avec des approches comme les appels en chaîne, simplifiant l'utilisation.

Étiquettes: Java Builder Pattern Design Patterns Object Construction

Publié le 24 juin à 16h51