Menu
Coddy logo textTech

Patron Fabrique

Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 55 sur 61.

Le pattern Factory centralise la création d’objets dans une seule fonction. Au lieu de disperser le code d’appel à malloc et d’initialisation dans tout votre programme, vous appelez une fonction qui décide quoi créer et renvoie un objet prêt à l’emploi.

Ce modèle est particulièrement puissant lorsqu’il est combiné au polymorphisme. Une fabrique peut renvoyer différents types concrets via un pointeur de base commun, en masquant les détails de la création à l’appelant. L’appelant demande simplement « une forme » et la fabrique décide de construire un cercle, un rectangle ou autre chose.

Voici une implémentation typique d’une fabrique :

typedef enum {
    SHAPE_CIRCLE,
    SHAPE_RECTANGLE
} ShapeType;

Shape* create_shape(ShapeType type) {
    switch (type) {
        case SHAPE_CIRCLE:
            return (Shape*)create_circle(5.0);
        case SHAPE_RECTANGLE:
            return (Shape*)create_rectangle(4.0, 3.0);
        default:
            return NULL;
    }
}

La factory prend un identifiant (généralement un enum) et utilise une instruction switch pour déterminer quel constructor appeler. Elle renvoie un Shape* quel que soit le type réel créé. L’appelant n’a pas besoin de connaître Circle ou Rectangle. Il travaille simplement avec le type base :

Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s);  // appel polymorphe
free_shape(s);

Ce modèle facilite l’ajout de nouveaux types : il suffit d’ajouter une nouvelle valeur d’énumération et un nouveau cas dans la fabrique. Le reste de votre code reste inchangé.

challenge icon

Défi

Facile

Construisons une Pet Factory : un système qui crée différents types d’animaux de compagnie באמצעות une seule fonction d’usine. Au lieu de disperser la logique de création dans tout votre code, vous allez la centraliser en un seul endroit qui détermine quel type d’animal créer en fonction d’un identifiant d’entrée.

Vous allez organiser votre code sur trois fichiers :

  • pet.h : définissez une énumération PetType avec les valeurs PET_DOG, PET_CAT et PET_BIRD. Créez une structure de base Pet qui contient un pointeur de fonction pour speak (qui prend un const Pet* et ne renvoie rien). Déclarez la fonction d’usine create_pet, qui prend un PetType et renvoie un Pet*, ainsi qu’une fonction free_pet pour le nettoyage.
  • pet.c : définissez trois structures concrètes d’animaux, Dog, Cat et Bird, chacune intégrant Pet comme premier membre. Implémentez une fonction speak pour chaque type :
    • Les dog affichent : Woof!
    • Les Cat affichent : Meow!
    • Les Bird affichent : Tweet!
    Créez des fonctions constructeur pour chaque type d’animal afin d’allouer de la mémoire et de relier la fonction speak appropriée. Implémentez ensuite l’usine create_pet : utilisez une instruction switch sur le PetType pour appeler le constructeur correct et renvoyer le résultat sous forme de Pet*. Pour les types invalides, renvoyez NULL. Implémentez free_pet pour libérer la mémoire allouée.
  • main.c : lisez un entier représentant le type d’animal (0 pour dog, 1 pour cat, 2 pour bird). Utilisez votre usine pour créer l’animal approprié, appelez sa fonction speak de manière polymorphe via le pointeur de base Pet*, puis libérez l’animal.

Votre programme recevra une entrée : un entier indiquant quel animal créer.

Exemple de sortie lorsque l’entrée est 0 :

Woof!

Exemple de sortie lorsque l’entrée est 1 :

Meow!

Exemple de sortie lorsque l’entrée est 2 :

Tweet!

L’intérêt du modèle Factory est que main.c n’a pas besoin de connaître les structures Dog, Cat ou Bird. Il ne travaille qu’avec le type de base Pet. Ajouter ultérieurement un nouveau type d’animal signifie ajouter une nouvelle valeur d’énumération et un nouveau case dans l’usine, sans modifier le code qui utilise les animaux.

Essayez vous-même

#include <stdio.h>
#include "pet.h"

int main(void) {
    int type;
    scanf("%d", &type);
    
    // TODO: Utilisez la factory pour créer le pet approprié
    // Indice : Castez l'int en PetType
    
    // TODO: Appelez la fonction speak de manière polymorphe via le pointeur Pet*
    
    // TODO: Libérez le pet
    
    return 0;
}
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

Entraînez-vous par vous-même : Compilateur C en ligne