Parlez-moi du pattern Factory.
sobes.tech IA
Réponse de l'IA
Une usine est un patron de conception creational qui fournit une interface commune pour créer des objets dans la superclasse, tandis que les sous-classes peuvent modifier le type d'objets créés.
-
Fournisseur simple (Simple Factory): Ce n'est pas un pattern à part entière, mais plutôt une idiome. Une classe avec une méthode qui crée des objets en fonction des paramètres d'entrée.
package main import "fmt" type Product interface { Use() } type ConcreteProductA struct{} func (p *ConcreteProductA) Use() { fmt.Println("Utilisation du Produit Concret A") } type ConcreteProductB struct{} func (p *ConcreteProductB) Use() { fmt.Println("Utilisation du Produit Concret B") } type SimpleFactory struct{} func (f *SimpleFactory) CreateProduct(t string) Product { switch t { case "A": return &ConcreteProductA{} case "B": return &ConcreteProductB{} default: return nil } } func main() { factory := SimpleFactory{} productA := factory.CreateProduct("A") productA.Use() productB := factory.CreateProduct("B") productB.Use() } -
Méthode de la fabrique (Factory Method): Définit une interface pour créer un objet, mais permet aux sous-classes de décider quelle classe instancier.
package main import "fmt" // Interface du produit type Product interface { Operation() string } // Produit concret A type ConcreteProduct1 struct{} func (p *ConcreteProduct1) Operation() string { return "Résultat du ConcreteProduct1" } // Produit concret B type ConcreteProduct2 struct{} func (p *ConcreteProduct2) Operation() string { return "Résultat du ConcreteProduct2" } // Interface du créateur type Creator interface { FactoryMethod() Product SomeOperation() string } // Structure de base du créateur type BaseCreator struct{} func (bc *BaseCreator) SomeOperation() string { // Appel de la méthode de fabrique pour obtenir un objet produit product := bc.FactoryMethod() // Utilisation du produit result := "Le code du créateur a travaillé avec " + product.Operation() return result } // Créateur concret A type ConcreteCreator1 struct { BaseCreator } func (cc *ConcreteCreator1) FactoryMethod() Product { return &ConcreteProduct1{} // Crée un produit concret A } // Créateur concret B type ConcreteCreator2 struct { BaseCreator } func (cc *ConcreteCreator2) FactoryMethod() Product { return &ConcreteProduct2{} // Crée un produit concret B } func main() { // Exemple d'utilisation creator1 := &ConcreteCreator1{} fmt.Println(creator1.SomeOperation()) creator2 := &ConcreteCreator2{} fmt.Println(creator2.SomeOperation()) } -
Fournisseur abstrait (Abstract Factory): Fournit une interface pour créer des familles d'objets liés ou dépendants sans spécifier leurs classes concrètes.
package main import "fmt" // Interface du produit A type AbstractProductA interface { UseProductA() string } // Produit A1 concret type ConcreteProductA1 struct{} func (*ConcreteProductA1) UseProductA() string { return "Le résultat du produit A1." } // Produit A2 concret type ConcreteProductA2 struct{} func (*ConcreteProductA2) UseProductA() string { return "Le résultat du produit A2." } // Interface du produit B type AbstractProductB interface { UseProductB() string AnotherFunctionB(collaborator AbstractProductA) string // Interaction avec le produit A } // Produit B1 concret type ConcreteProductB1 struct{} func (*ConcreteProductB1) UseProductB() string { return "Le résultat du produit B1." } // Interaction B1 avec n'importe quel type d'AbstractProductA func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("Le résultat du B1 collaborant avec le (%s)", result) } // Produit B2 concret type ConcreteProductB2 struct{} func (*ConcreteProductB2) UseProductB() string { return "Le résultat du produit B2." } // Interaction B2 avec n'importe quel type d'AbstractProductA func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("Le résultat du B2 collaborant avec le (%s)", result) } // Interface de la fabrique abstraite type AbstractFactory interface { CreateProductA() AbstractProductA CreateProductB() AbstractProductB } // Fábrica concreta 1 type ConcreteFactory1 struct{} func (*ConcreteFactory1) CreateProductA() AbstractProductA { return &ConcreteProductA1{} } func (*ConcreteFactory1) CreateProductB() AbstractProductB { return &ConcreteProductB1{} } // Fábrica concreta 2 type ConcreteFactory2 struct{} func (*ConcreteFactory2) CreateProductA() AbstractProductA { return &ConcreteProductA2{} } func (*ConcreteFactory2) CreateProductB() AbstractProductB { return &ConcreteProductB2{} } // Código cliente que trabaja con la fábrica func ClientCode(factory AbstractFactory) { productA := factory.CreateProductA() productB := factory.CreateProductB() fmt.Println(productB.UseProductB()) fmt.Println(productB.AnotherFunctionB(productA)) } func main() { fmt.Println("Cliente: Probando código cliente con el primer tipo de fábrica:") ClientCode(&ConcreteFactory1{}) fmt.Println("Cliente: Probando el mismo código cliente con el segundo tipo de fábrica:") ClientCode(&ConcreteFactory2{}) }
La principal diferencia entre el método de fábrica y la fábrica abstracta: El método de fábrica crea productos individuales, mientras que la fábrica abstracta crea familias de productos.
| Nombre del patrón | Descripción | Cuándo usar |
|---|---|---|
| Fábrica simple | Método en una clase para crear objetos de diferentes tipos. | Para crear objetos simples sin necesidad de una jerarquía de fábricas. |
| Método de fábrica | Interfaz para crear un objeto, permitiendo que las subclases decidan qué clase instanciar. | Cuando una clase no puede predecir el tipo de objetos que debe crear. |
| Fábrica abstracta | Interfaz para crear familias de objetos relacionados. | Cuando el sistema debe ser independiente del modo en que se crean y representan sus productos. |
El patrón Fábrica fomenta un acoplamiento débil del código y facilita la adición de nuevos tipos de productos sin modificar el código cliente.