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é.
Défi
FacileConstruisons 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érationPetTypeavec les valeursPET_DOG,PET_CATetPET_BIRD. Créez une structure de basePetqui contient un pointeur de fonction pourspeak(qui prend unconst Pet*et ne renvoie rien). Déclarez la fonction d’usinecreate_pet, qui prend unPetTypeet renvoie unPet*, ainsi qu’une fonctionfree_petpour le nettoyage.pet.c: définissez trois structures concrètes d’animaux,Dog,CatetBird, chacune intégrantPetcomme premier membre. Implémentez une fonction speak pour chaque type :- Les dog affichent :
Woof! - Les Cat affichent :
Meow! - Les Bird affichent :
Tweet!
create_pet: utilisez une instruction switch sur lePetTypepour appeler le constructeur correct et renvoyer le résultat sous forme dePet*. Pour les types invalides, renvoyezNULL. Implémentezfree_petpour libérer la mémoire allouée.- Les dog affichent :
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 fonctionspeakde manière polymorphe via le pointeur de basePet*, 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;
}
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
1Bases de la programmation modulaire
Fichiers d'en-têteGardes d'inclusionFichiers sourcesFonctions statiquesRécapitulatif : Calculatrice modulaire4Encapsulation
Concept des pointeurs opaquesDéfinir des structures opaquesGetters et settersValidation dans les settersRécapitulatif : La boîte secrète2Objets et méthodes
Structs comme objetsLe pointeur 'Self'Rigueur du mot-clé constPointeur vs ValeurMéthodes utilitairesRécapitulatif : Point Manager5Projet : Compte bancaire simple
Configuration du projetImplémentation du compte8Polymorphisme
Pointeurs de fonctions dans les structuresSimulation de méthodesLe concept d'interfaceImplémentation d'interfacesItération polymorphiqueRécapitulatif : Greeter11Patrons de conception en C
Patron SingletonPatron FabriquePatron ItérateurRécapitulatif : Logger Factory3Cycle de vie des objets
Pattern de constructeurPattern de destructeurInitialisation sur la pileCopie profondeRécapitulatif : String Wrapper6Héritage par composition
Imbrication de structLa règle du premier membreAccès aux membres parentsUpcastingRécapitulatif : Hiérarchie des formes9Projet : Dessinateur de formes
Aperçu du projetImplémentation du cercleImplémentation du rectangleUtilisation polymorpheConteneur de formesEntraînez-vous par vous-même : Compilateur C en ligne