Menu
Coddy logo textTech

Patron Fabrique

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 66 sur 87.

Le Factory Pattern est un patron de conception de création qui délègue la création d'objets à une méthode ou une classe séparée. Au lieu d'utiliser new directement dans votre code, vous demandez à une fabrique de créer des objets pour vous. Ceci est particulièrement utile lorsque vous avez plusieurs classes liées qui partagent une interface ou un parent commun.

Considérez un système de notification capable d'envoyer des e-mails, des SMS ou des notifications push. Sans fabrique (factory), votre code devrait connaître chaque classe concrète :

// Sans Factory - le client doit connaître toutes les classes concrètes
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

Avec le Factory Pattern, vous centralisez cette logique de création :

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

Désormais, le code client est plus propre et ne dépend pas de classes concrètes :

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // Sortie : Email: Hello!

L'avantage principal est que l'ajout de nouveaux types de notification nécessite seulement la mise à jour de la fabrique — le code client reste inchangé. Cela suit le principe de la programmation vers une interface, rendant votre système plus flexible et plus facile à étendre.

challenge icon

Défi

Facile

Construisons un système de dessin de formes en utilisant le Factory Pattern ! Au lieu de créer des objets de forme directement dans votre code, vous allez centraliser la logique de création dans une fabrique qui produit différents types de formes basés sur un simple identifiant sous forme de chaîne de caractères.

Vous organiserez votre code sur quatre fichiers :

  • Shape.java : Définissez une interface appelée Shape qui sert de contrat commun pour toutes les formes. Votre interface doit déclarer une seule méthode draw() qui ne retourne rien mais affiche des informations sur la forme en cours de dessin.
  • Shapes.java : Créez trois classes qui implémentent votre interface Shape :

    Circle - sa méthode draw() doit afficher Drawing a Circle

    Rectangle - sa méthode draw() doit afficher Drawing a Rectangle

    Triangle - sa méthode draw() doit afficher Drawing a Triangle

  • ShapeFactory.java : Créez la classe factory qui gère la création des formes. Votre ShapeFactory doit avoir une méthode statique createShape(String type) qui retourne une Shape. En fonction du paramètre type :
    • Si type est égal à "circle", retournez un nouveau Circle
    • Si type est égal à "rectangle", retournez un nouveau Rectangle
    • Si type est égal à "triangle", retournez un nouveau Triangle
    • Pour toute autre valeur, retournez null
  • Main.java : Rassemblez votre système de fabrique ! Vous recevrez deux entrées : deux types de formes (tous deux des Strings).

    Pour chaque entrée, utilisez votre ShapeFactory pour créer la forme et stockez-la dans une variable Shape. Si la fabrique retourne une forme valide (non nulle), appelez sa méthode draw(). Si elle retourne nulle, affichez Unknown shape: [type] où [type] est l'entrée qui a été fournie.

    Traitez les deux entrées dans l'ordre, chacune sur sa propre ligne de sortie.

Vous recevrez deux entrées dans l'ordre : le premier type de forme (String) et le second type de forme (String).

Remarquez comment votre classe Main n'utilise jamais new Circle() ou new Rectangle() directement — elle ne connaît que l'interface Shape et demande à la fabrique de créer des objets. C'est toute la puissance du Factory Pattern : le code client est découplé des classes concrètes !

Aide-mémoire

Le Factory Pattern (ou patron de méthode de fabrique) est un patron de conception de création qui délègue la création d'objets à une méthode ou une classe distincte, centralisant la logique de création et découplant le code client des implémentations concrètes.

Au lieu d'instancier des objets directement avec new, vous utilisez une méthode de fabrique :

// Sans Factory - le client dépend des classes concrètes
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

Avec le Factory Pattern, définissez une interface commune et des implémentations concrètes :

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

Créez une classe de fabrique avec une méthode de création statique :

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

Le code client utilise la fabrique au lieu de l'instanciation directe :

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // Résultat : Email: Hello!

Avantages : L'ajout de nouveaux types nécessite uniquement la mise à jour de la fabrique — le code client reste inchangé. Cela suit le principe de programmation vers une interface, rendant les systèmes plus flexibles et plus faciles à étendre.

Essayez vous-même

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire deux types de formes
        String type1 = scanner.nextLine();
        String type2 = scanner.nextLine();
        
        // TODO: Utiliser ShapeFactory pour créer la première forme
        // Si la forme n'est pas null, appeler draw()
        // Si la forme est null, afficher "Unknown shape: [type]"
        
        // TODO: Faire la même chose pour la deuxième forme
        
    }
}
quiz iconTestez-vous

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