Ispričaj mi o obrascu Factory.
sobes.tech АИ
Одговор од АИ
Фабрика — то је образац креирања који пружа општи интерфејс за креирање објеката у суперкласама, док подкласе могу мењати тип објеката које креирају.
-
Једноставна фабрика (Simple Factory): Није у потпуности образац, већ више идиома. Класа са методом која креира објекте на основу улазних параметара.
package main import "fmt" type Product interface { Use() } type ConcreteProductA struct{} func (p *ConcreteProductA) Use() { fmt.Println("Користи Конкретан Производ А") } type ConcreteProductB struct{} func (p *ConcreteProductB) Use() { fmt.Println("Користи Конкретан Производ Б") } 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 } // Конкретан производ А type ConcreteProduct1 struct{} func (p *ConcreteProduct1) Operation() string { return "Резултат од Конкретног Производа 1" } // Конкретан производ Б type ConcreteProduct2 struct{} func (p *ConcreteProduct2) Operation() string { return "Резултат од Конкретног Производа 2" } // Интерфејс креираоца type Creator interface { FactoryMethod() Product SomeOperation() string } // Базна структура креираоца type BaseCreator struct{} func (bc *BaseCreator) SomeOperation() string { // Позив фабричног метода за добијање производа product := bc.FactoryMethod() // Коришћење производа result := "Креирач: исти код креираоца управља са " + product.Operation() return result } // Конкретни креирач А type ConcreteCreator1 struct { BaseCreator } func (cc *ConcreteCreator1) FactoryMethod() Product { return &ConcreteProduct1{} // Креира Конкретан Производ А } // Конкретни креирач Б type ConcreteCreator2 struct { BaseCreator } func (cc *ConcreteCreator2) FactoryMethod() Product { return &ConcreteProduct2{} // Креира Конкретан Производ Б } func main() { // Пример коришћења creator1 := &ConcreteCreator1{} fmt.Println(creator1.SomeOperation()) creator2 := &ConcreteCreator2{} fmt.Println(creator2.SomeOperation()) } -
Апстрактна фабрика (Abstract Factory): Пружа интерфејс за креирање породице повезаних или зависних објеката без навођења њихових конкретних класа.
package main import "fmt" // Интерфејс производа А type AbstractProductA interface { UseProductA() string } // Конкретан производ А1 type ConcreteProductA1 struct{} func (*ConcreteProductA1) UseProductA() string { return "Резултат производа А1." } // Конкретан производ А2 type ConcreteProductA2 struct{} func (*ConcreteProductA2) UseProductA() string { return "Резултат производа А2." } // Интерфејс производа Б type AbstractProductB interface { UseProductB() string AnotherFunctionB(collaborator AbstractProductA) string // Взаимодејство са производом А } // Конкретан производ Б1 type ConcreteProductB1 struct{} func (*ConcreteProductB1) UseProductB() string { return "Резултат производа Б1." } // Взаимодејство Б1 са било којим типом AbstractProductA func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("Резултат Б1 у сарадњи са (%s)", result) } // Конкретан производ Б2 type ConcreteProductB2 struct{} func (*ConcreteProductB2) UseProductB() string { return "Резултат производа Б2." } // Взаимодејство Б2 са било којим типом AbstractProductA func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string { result := collaborator.UseProductA() return fmt.Sprintf("Резултат Б2 у сарадњи са (%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{}) }
Главна разлика између Фабричног метода и Апстрактне фабрике: Фабрички метод креира појединачне производе, док Апстрактна фабрика креира породице производа.
| Назив образца | Опис | Када користити |
|---|---|---|
| Једноставна фабрика | Метод у једној класи за креирање различитих типова објеката. | За једноставно креирање објеката без потребе за хијерархијом фабрика. |
| Фабрички метод | Интерфејс за креирање објекта, који омогућава подкласама да одлуче који ће класу инстанцирати. | Када класа не може предвидети типове објеката које треба да креира. |
| Апстрактна фабрика | Интерфејс за креирање породице повезаних објеката. | Када систем треба да буде независан од начина креирања и представљања својих производа. |
Образац Фабрика доприноси слабој повезаности кода и олакшава додавање нових типова производа без измене клиентског кода.