Patron Fabrique
Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy — leçon 53 sur 70.
Le pattern Factory est un patron de création qui délègue la création d'objets à une méthode ou une classe distincte. Au lieu d'utiliser new directement dans votre code, vous demandez à une fabrique de créer des objets pour vous. Cela centralise la logique de création et rend votre code plus flexible.
Considérez un scénario dans lequel vous devez créer différents types de documents. Sans une fabrique (factory), votre code devient étroitement couplé à des classes spécifiques :
// Sans Factory - logique de création dispersée
IDocument doc;
if (type == "pdf")
doc = new PdfDocument();
else if (type == "word")
doc = new WordDocument();Une fabrique encapsule cette prise de décision en un seul endroit :
public interface IDocument
{
void Open();
}
public class PdfDocument : IDocument
{
public void Open() => Console.WriteLine("Opening PDF");
}
public class WordDocument : IDocument
{
public void Open() => Console.WriteLine("Opening Word");
}
public class DocumentFactory
{
public IDocument Create(string type)
{
return type switch
{
"pdf" => new PdfDocument(),
"word" => new WordDocument(),
_ => throw new ArgumentException("Unknown type")
};
}
}Désormais, le code client demande simplement ce dont il a besoin sans connaître les classes concrètes :
var factory = new DocumentFactory();
IDocument doc = factory.Create("pdf");
doc.Open(); // Ouverture du PDFLe pattern Factory brille lorsque vous devez ajouter de nouveaux types plus tard. L'ajout d'un SpreadsheetDocument ne nécessite des modifications que dans la fabrique, et non partout où les documents sont créés. Cette séparation rend votre base de code plus facile à maintenir et à tester.
Défi
FacileConstruisons un système de notification en utilisant le pattern Factory. Au lieu de créer différents types de notification directement dans votre code, vous allez centraliser la logique de création dans une classe d'usine (factory) qui décide quelle notification créer en fonction d'un simple identifiant sous forme de chaîne de caractères.
Vous organiserez votre code sur trois fichiers :
Notification.cs: Définissez une interfaceINotificationdans l'espace de nomsNotificationsavec une seule méthodeSend(string message)qui retourne une chaîne de caractères. Créez ensuite trois classes qui implémentent cette interface :EmailNotification- retourne"Email: {message}"SmsNotification- retourne"SMS: {message}"PushNotification- retourne"Push: {message}"
NotificationFactory.cs: Créez une classeNotificationFactorydans le même espace de noms avec une méthodeCreate(string type)qui retourne l'objetINotificationapproprié en fonction de la chaîne de caractères type :"email"retourne uneEmailNotification"sms"retourne uneSmsNotification"push"retourne unePushNotification
EmailNotificationpar défaut.Program.cs: Rassemblez le tout en créant une instance de l'usine et en l'utilisant pour créer des notifications basées sur l'entrée. L'usine gère toute la prise de décision concernant la classe concrète à instancier.
Vous recevrez deux entrées :
- Le type de notification (par exemple,
sms) - Le message à envoyer (par exemple,
Your order has shipped)
Utilisez votre usine pour créer le type de notification approprié, puis appelez sa méthode Send avec le message et affichez le résultat.
Par exemple, si les entrées sont push et Meeting in 5 minutes, la sortie devrait être :
Push: Meeting in 5 minutesRemarquez comment votre code principal n'utilise jamais new EmailNotification() ou similaire - il demande simplement à l'usine ce dont il a besoin. Si vous ajoutez plus tard une SlackNotification, vous n'aurez qu'à mettre à jour l'usine, et non chaque endroit qui crée des notifications !
Aide-mémoire
Le pattern Factory (ou patron 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 rendant le code plus flexible.
Sans fabrique, la création d'objets est dispersée et fortement couplée :
// Sans Factory - logique de création dispersée
IDocument doc;
if (type == "pdf")
doc = new PdfDocument();
else if (type == "word")
doc = new WordDocument();Avec une fabrique, la logique de création est encapsulée en un seul endroit :
public interface IDocument
{
void Open();
}
public class PdfDocument : IDocument
{
public void Open() => Console.WriteLine("Opening PDF");
}
public class WordDocument : IDocument
{
public void Open() => Console.WriteLine("Opening Word");
}
public class DocumentFactory
{
public IDocument Create(string type)
{
return type switch
{
"pdf" => new PdfDocument(),
"word" => new WordDocument(),
_ => throw new ArgumentException("Unknown type")
};
}
}Le code client demande des objets sans connaître les classes concrètes :
var factory = new DocumentFactory();
IDocument doc = factory.Create("pdf");
doc.Open(); // Ouverture du PDFLe pattern Factory facilite l'ajout de nouveaux types - les modifications sont isolées dans la fabrique, et non dispersées dans l'ensemble de la base de code.
Essayez vous-même
using System;
using Notifications;
class Program
{
public static void Main(string[] args)
{
// Lire l'entrée
string type = Console.ReadLine();
string message = Console.ReadLine();
// TODO: Créer une instance de NotificationFactory
// TODO: Utiliser la fabrique pour créer la notification appropriée
// TODO: Appeler la méthode Send et afficher le résultat
}
}
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 externesEspaces de noms et directivesIntro aux classes et objetsLe mot-clé 'this'Méthodes et paramètresChamps vs PropriétésConstructeursInitialiseurs d'objetsRécapitulatif - Calculatrice simple4Héritage
Syntaxe de base de l'héritage (:)Le mot-clé 'base'Mots-clés Virtual & OverrideClasses scelléesLa classe de base 'object'Récapitulatif - Hiérarchie des employés7Fonctionnalités avancées
Surcharge d'opérateursIndexeurs (this[])Redéfinition de ToString()Méthodes d'extensionRécapitulatif - Liste personnalisée10Patrons de conception - Partie 1
Introduction aux patrons de conceptionSingleton Thread-SafePatron FabriquePatron Observateur (Événements)Patron Stratégie2Propriétés et membres statiques
Propriétés auto-implémentéesPropriétés en lecture/écriture seuleChamps et méthodes statiquesClasses statiquesMembres à corps d'expression5Polymorphisme & Interfaces
Polymorphisme : Compilation vs ExécutionInterface vs Classe AbstraiteInterfaces MultiplesInterfaces ExplicitesUpcasting & DowncastingRécapitulatif - Calculateur de Formes8Concepts avancés de la POO
Composition plutôt qu'héritageGénériques (Classes et Méthodes)Délégués et ÉvénementsAttributs et RéflexionIDisposable et l'instruction usingBases de l'Injection de Dépendances11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Architecture des classes
Données d'instance vs statiquesMots-clés 'readonly' & 'const'Champs de supportRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Modificateurs d'accèsPropriétés pour l'encapsulationImplémentation du masquage de donnéesPatterns d'immuabilitéRécapitulatif - Dossiers d'étudiants12Projet : Système de gestion de bibliothèque
Structure du projetModèles Livre et Utilisateur