Разкажи ми за патърна Factory.
sobes.tech AI
Отговор от AI
Фабрика — това е порождащ патърн за дизайн, който предоставя общ интерфейс за създаване на обекти в суперкласата, докато подкласите могат да променят типа на създаваните обекти.
-
Проста фабрика (Simple Factory): Не е чист патърн, по-скоро идиома. Клас с метод, който създава обекти въз основа на входните параметри.
package main import "fmt" type Product interface { Use() } type ConcreteProductA struct{} func (p *ConcreteProductA) Use() { fmt.Println("Използване на Concrete Product A") } type ConcreteProductB struct{} func (p *ConcreteProductB) Use() { fmt.Println("Използване на 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 "Резултат от ConcreteProduct1" } // Конкретен продукт B type ConcreteProduct2 struct{} func (p *ConcreteProduct2) Operation() string { return "Резултат от ConcreteProduct2" } // Интерфейс на създателя type Creator interface { FactoryMethod() Product SomeOperation() string } // Базова структура на създателя type BaseCreator struct{} func (bc *BaseCreator) SomeOperation() string { // Вика фабричния метод за получаване на обект продукт product := bc.FactoryMethod() // Използване на продукта result := "Създавач: същият код на създателя току-що работи с " + 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 "Резултат от продукт A1." } // Конкретен продукт A2 type ConcreteProductA2 struct{} func (*ConcreteProductA2) UseProductA() string { return "Резултат от продукт A2." } // Интерфейс на продукт B type AbstractProductB interface { UseProductB() string AnotherFunctionB(collaborator AbstractProductA) string // Взаимодействие с продукт A } // Конкретен продукт B1 type ConcreteProductB1 struct{} func (*ConcreteProductB1) UseProductB() string { return "Резултат от продукт B1." } func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("Резултат от B1 сътрудничество с (%s)", result) } // Конкретен продукт B2 type ConcreteProductB2 struct{} func (*ConcreteProductB2) UseProductB() string { return "Резултат от продукт B2." } func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("Резултат от B2 сътрудничество с (%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("Клиент: Тестиране на клиентски код с първия тип фабрика:") ClientCode(&ConcreteFactory1{}) fmt.Println("Клиент: Тестиране на същия клиентски код с втория тип фабрика:") ClientCode(&ConcreteFactory2{}) }
Основната разлика между Фабричния метод и Абстрактната фабрика: Фабричният метод създава единични продукти, докато Абстрактната фабрика създава семейства продукти.
| Име на шаблона | Описание | Кога да го използваме |
|---|---|---|
| Простата фабрика | Метод в един клас за създаване на обекти от различни типове. | За простото създаване на обекти без необходимост от йерархия на фабрики. |
| Фабричен метод | Интерфейс за създаване на обект, позволяващ на подкласите да решат кой клас да инстанцират. | Когато класът не може да предвиди типа на обектите, които трябва да създаде. |
| Абстрактна фабрика | Предоставя интерфейс за създаване на семейства свързани или зависими обекти без да указва конкретните им класове. | Когато системата трябва да бъде независима от начина на създаване и представяне на продуктите. |
Шаблонът фабрика насърчава слака свързаност на кода и улеснява добавянето на нови типове продукти без промяна в клиентския код.