Расскажи о паттерне Фабрика (Factory).
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Фабрика — это порождающий паттерн проектирования, который предоставляет общий интерфейс для создания объектов в суперклассе, в то время как подклассы могут изменять тип создаваемых объектов.
-
Простая фабрика (Simple Factory): Не является паттерном в чистом виде, скорее идиома. Класс с методом, который создает объекты, исходя из входных параметров.
package main import "fmt" type Product interface { Use() } type ConcreteProductA struct{} func (p *ConcreteProductA) Use() { fmt.Println("Using Concrete Product A") } type ConcreteProductB struct{} func (p *ConcreteProductB) Use() { fmt.Println("Using Concrete Product 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() } -
Фабричный метод (Factory Method): Определяет интерфейс для создания объекта, но позволяет подклассам решать, какой класс инстанцировать.
package main import "fmt" // Интерфейс продукта type Product interface { Operation() string } // Конкретный продукт A type ConcreteProduct1 struct{} func (p *ConcreteProduct1) Operation() string { return "Result of the ConcreteProduct1" } // Конкретный продукт B type ConcreteProduct2 struct{} func (p *ConcreteProduct2) Operation() string { return "Result of the ConcreteProduct2" } // Интерфейс создателя type Creator interface { FactoryMethod() Product SomeOperation() string } // Базовая структура создателя type BaseCreator struct{} func (bc *BaseCreator) SomeOperation() string { // Вызов фабричного метода для получения объекта продукта product := bc.FactoryMethod() // Использование продукта result := "Creator: The same creator's code has just worked with " + product.Operation() return result } // Конкретный создатель A type ConcreteCreator1 struct { BaseCreator } func (cc *ConcreteCreator1) FactoryMethod() Product { return &ConcreteProduct1{} // Создает Конкретный продукт A } // Конкретный создатель B type ConcreteCreator2 struct { BaseCreator } func (cc *ConcreteCreator2) FactoryMethod() Product { return &ConcreteProduct2{} // Создает Конкретный продукт B } func main() { // Пример использования creator1 := &ConcreteCreator1{} fmt.Println(creator1.SomeOperation()) creator2 := &ConcreteCreator2{} fmt.Println(creator2.SomeOperation()) } -
Абстрактная фабрика (Abstract Factory): Предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
package main import "fmt" // Интерфейс продукт A type AbstractProductA interface { UseProductA() string } // Конкретный продукт A1 type ConcreteProductA1 struct{} func (*ConcreteProductA1) UseProductA() string { return "The result of the product A1." } // Конкретный продукт A2 type ConcreteProductA2 struct{} func (*ConcreteProductA2) UseProductA() string { return "The result of the product A2." } // Интерфейс продукт B type AbstractProductB interface { UseProductB() string AnotherFunctionB(collaborator AbstractProductA) string // Взаимодействие с продуктом A } // Конкретный продукт B1 type ConcreteProductB1 struct{} func (*ConcreteProductB1) UseProductB() string { return "The result of the product B1." } // Взаимодействие B1 с любым типом AbstractProductA func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("The result of the B1 collaborating with the (%s)", result) } // Конкретный продукт B2 type ConcreteProductB2 struct{} func (*ConcreteProductB2) UseProductB() string { return "The result of the product B2." } // Взаимодействие B2 с любым типом AbstractProductA func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("The result of the B2 collaborating with the (%s)", result) } // Интерфейс абстрактной фабрики type AbstractFactory interface { CreateProductA() AbstractProductA CreateProductB() AbstractProductB } // Конкретная фабрика 1 type ConcreteFactory1 struct{} func (*ConcreteFactory1) CreateProductA() AbstractProductA { return &ConcreteProductA1{} } func (*ConcreteFactory1) CreateProductB() AbstractProductB { return &ConcreteProductB1{} } // Конкретная фабрика 2 type ConcreteFactory2 struct{} func (*ConcreteFactory2) CreateProductA() AbstractProductA { return &ConcreteProductA2{} } func (*ConcreteFactory2) CreateProductB() AbstractProductB { return &ConcreteProductB2{} } // Клиентский код, работающий с фабрикой func ClientCode(factory AbstractFactory) { productA := factory.CreateProductA() productB := factory.CreateProductB() fmt.Println(productB.UseProductB()) fmt.Println(productB.AnotherFunctionB(productA)) } func main() { fmt.Println("Client: Testing client code with the first factory type:") ClientCode(&ConcreteFactory1{}) fmt.Println("Client: Testing the same client code with the second factory type:") ClientCode(&ConcreteFactory2{}) }
Главное различие между Фабричным методом и Абстрактной фабрикой: Фабричный метод создает одиночные продукты, тогда как Абстрактная фабрика создает семейства продуктов.
| Название паттерна | Описание | Когда использовать |
|---|---|---|
| Простая фабрика | Метод в одном классе для создания объектов разных типов. | Для простого создания объектов без необходимости иерархии фабрик. |
| Фабричный метод | Интерфейс для создания объекта, позволяющий подклассам решать, какой класс инстанцировать. | Когда класс не может предсказать тип объектов, которые он должен создать. |
| Абстрактная фабрика | Интерфейс для создания семейств связанных объектов. | Когда система должна быть независима от способа создания и представления ее продуктов. |
Паттерн Фабрика способствует слабой связанности кода и облегчает добавление новых типов продуктов без изменения клиентского кода.