Háblame del patrón Factory.
sobes.tech AI
Respuesta de la IA
La fábrica es un patrón de diseño creacional que proporciona una interfaz común para crear objetos en la superclase, mientras que las subclases pueden modificar el tipo de objetos creados.
-
Fábrica simple (Simple Factory): No es un patrón en su forma pura, sino más bien una idiomática. Una clase con un método que crea objetos basándose en los parámetros de entrada.
package main import "fmt" type Product interface { Use() } type ConcreteProductA struct{} func (p *ConcreteProductA) Use() { fmt.Println("Usando Producto Concreto A") } type ConcreteProductB struct{} func (p *ConcreteProductB) Use() { fmt.Println("Usando Producto Concreto 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étodo de fábrica (Factory Method): Define una interfaz para crear un objeto, pero permite que las subclases decidan qué clase instanciar.
package main import "fmt" // Interfaz de producto type Product interface { Operation() string } // Producto concreto A type ConcreteProduct1 struct{} func (p *ConcreteProduct1) Operation() string { return "Resultado del ProductoConcreto1" } // Producto concreto B type ConcreteProduct2 struct{} func (p *ConcreteProduct2) Operation() string { return "Resultado del ProductoConcreto2" } // Interfaz del creador type Creator interface { FactoryMethod() Product SomeOperation() string } // Estructura base del creador type BaseCreator struct{} func (bc *BaseCreator) SomeOperation() string { // Llamada al método de fábrica para obtener un objeto de producto product := bc.FactoryMethod() // Uso del producto result := "El código del creador ha trabajado con " + product.Operation() return result } // Creador concreto A type ConcreteCreator1 struct { BaseCreator } func (cc *ConcreteCreator1) FactoryMethod() Product { return &ConcreteProduct1{} // Crea Producto concreto A } // Creador concreto B type ConcreteCreator2 struct { BaseCreator } func (cc *ConcreteCreator2) FactoryMethod() Product { return &ConcreteProduct2{} // Crea Producto concreto B } func main() { // Ejemplo de uso creator1 := &ConcreteCreator1{} fmt.Println(creator1.SomeOperation()) creator2 := &ConcreteCreator2{} fmt.Println(creator2.SomeOperation()) } -
Fábrica abstracta (Abstract Factory): Proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.
package main import "fmt" // Interfaz de producto A type AbstractProductA interface { UseProductA() string } // Producto A1 concreto type ConcreteProductA1 struct{} func (*ConcreteProductA1) UseProductA() string { return "El resultado del producto A1." } // Producto A2 concreto type ConcreteProductA2 struct{} func (*ConcreteProductA2) UseProductA() string { return "El resultado del producto A2." } // Interfaz de producto B type AbstractProductB interface { UseProductB() string AnotherFunctionB(collaborator AbstractProductA) string // Interacción con producto A } // Producto B1 concreto type ConcreteProductB1 struct{} func (*ConcreteProductB1) UseProductB() string { return "El resultado del producto B1." } // Interacción B1 con cualquier tipo de AbstractProductA func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("El resultado del B1 colaborando con el (%s)", result) } // Producto B2 concreto type ConcreteProductB2 struct{} func (*ConcreteProductB2) UseProductB() string { return "El resultado del producto B2." } // Interacción B2 con cualquier tipo de AbstractProductA func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("El resultado del B2 colaborando con el (%s)", result) } // Interfaz de la fábrica abstracta 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.