Sobes.tech
Middle

Pověz mi o vzoru Factory.

sobes.tech AI

Odpověď od AI

Gyár — je to návrhový vzor vytvárania, ktorý poskytuje spoločné rozhranie na tvorbu objektov v nadtriede, zatiaľ čo podtriedy môžu meniť typ vytváraných objektov.

  • Jednoduchá továreň (Simple Factory): Nie je to úplný vzor, skôr idiom. Trieda s metódou, ktorá vytvára objekty na základe vstupných parametrov.

    package main
    
    import "fmt"
    
    type Product interface {
    	Use()
    }
    
    type ConcreteProductA struct{}
    
    func (p *ConcreteProductA) Use() {
    	fmt.Println("Použitie konkrétneho produktu A")
    }
    
    type ConcreteProductB struct{}
    
    func (p *ConcreteProductB) Use() {
    	fmt.Println("Použitie konkrétneho produktu 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()
    }
    
  • Fabrika metóda (Factory Method): Definuje rozhranie na vytváranie objektu, ale umožňuje podtriedam rozhodnúť, akú triedu inštanciu vytvoriť.

    package main
    
    import "fmt"
    
    // Rozhranie produktu
    type Product interface {
    	Operation() string
    }
    
    // Konkrétny produkt A
    type ConcreteProduct1 struct{}
    
    func (p *ConcreteProduct1) Operation() string {
    	return "Výsledok ConcreteProduct1"
    }
    
    // Konkrétny produkt B
    type ConcreteProduct2 struct{}
    
    func (p *ConcreteProduct2) Operation() string {
    	return "Výsledok ConcreteProduct2"
    }
    
    // Rozhranie tvorcu
    type Creator interface {
    	FactoryMethod() Product
    	SomeOperation() string
    }
    
    // Základná štruktúra tvorcu
    type BaseCreator struct{}
    
    func (bc *BaseCreator) SomeOperation() string {
    	// Volanie továrenskej metódy na získanie objektu produktu
    	product := bc.FactoryMethod()
    	// Použitie produktu
    	result := "Tvorca: Rovnaký kód, ktorý práve pracoval s " + product.Operation()
    	return result
    }
    
    // Konkrétny tvorca A
    type ConcreteCreator1 struct {
    	BaseCreator
    }
    
    func (cc *ConcreteCreator1) FactoryMethod() Product {
    	return &ConcreteProduct1{} // Vytvára konkrétny produkt A
    }
    
    // Konkrétny tvorca B
    type ConcreteCreator2 struct {
    	BaseCreator
    }
    
    func (cc *ConcreteCreator2) FactoryMethod() Product {
    	return &ConcreteProduct2{} // Vytvára konkrétny produkt B
    }
    
    func main() {
    	// Príklad použitia
    	creator1 := &ConcreteCreator1{}
    	fmt.Println(creator1.SomeOperation())
    
    	creator2 := &ConcreteCreator2{}
    	fmt.Println(creator2.SomeOperation())
    }
    
  • Abstraktná továreň (Abstract Factory): Poskytuje rozhranie na tvorbu súvislých alebo závislých objektových rodín bez určenia ich konkrétnych tried.

    package main
    
    import "fmt"
    
    // Rozhranie produktu A
    type AbstractProductA interface {
    	UseProductA() string
    }
    
    // Konkrétny produkt A1
    type ConcreteProductA1 struct{}
    
    func (*ConcreteProductA1) UseProductA() string {
    	return "Výsledok produktu A1."
    }
    
    // Konkrétny produkt A2
    type ConcreteProductA2 struct{}
    
    func (*ConcreteProductA2) UseProductA() string {
    	return "Výsledok produktu A2."
    }
    
    // Rozhranie produktu B
    type AbstractProductB interface {
    	UseProductB() string
    	AnotherFunctionB(collaborator AbstractProductA) string // Interakcia s produktom A
    }
    
    // Konkrétny produkt B1
    type ConcreteProductB1 struct{}
    
    func (*ConcreteProductB1) UseProductB() string {
    	return "Výsledok produktu B1."
    }
    
    func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("Výsledok B1 spolupráce s (%s)", result)
    }
    
    // Konkrétny produkt B2
    type ConcreteProductB2 struct{}
    
    func (*ConcreteProductB2) UseProductB() string {
    	return "Výsledok produktu B2."
    }
    
    func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("Výsledok B2 spolupráce s (%s)", result)
    }
    
    // Rozhranie abstraktnej továrne
    type AbstractFactory interface {
    	CreateProductA() AbstractProductA
    	CreateProductB() AbstractProductB
    }
    
    // Konkrétna továreň 1
    type ConcreteFactory1 struct{}
    
    func (*ConcreteFactory1) CreateProductA() AbstractProductA {
    	return &ConcreteProductA1{}
    }
    
    func (*ConcreteFactory1) CreateProductB() AbstractProductB {
    	return &ConcreteProductB1{}
    }
    
    // Konkrétna továreň 2
    type ConcreteFactory2 struct{}
    
    func (*ConcreteFactory2) CreateProductA() AbstractProductA {
    	return &ConcreteProductA2{}
    }
    
    func (*ConcreteFactory2) CreateProductB() AbstractProductB {
    	return &ConcreteProductB2{}
    }
    
    // Klientski kód pracujúci s továrňou
    func ClientCode(factory AbstractFactory) {
    	productA := factory.CreateProductA()
    	productB := factory.CreateProductB()
    
    	fmt.Println(productB.UseProductB())
    	fmt.Println(productB.AnotherFunctionB(productA))
    }
    
    func main() {
    	fmt.Println("Klient: Testovanie kódu klienta s prvým typom továrne:")
    	ClientCode(&ConcreteFactory1{})
    
    	fmt.Println("Klient: Testovanie rovnakého kódu klienta s druhým typom továrne:")
    	ClientCode(&ConcreteFactory2{})
    }
    

Hlavný rozdiel medzi Fabrikou metódou a Abstraktnou továrňou: Fabrika metóda vytvára jednotlivé produkty, zatiaľ čo Abstraktná továreň vytvára rodiny produktov.

Názov vzoru Popis Kedy použiť
Jednoduchá továreň Metóda v jednej triede na tvorbu rôznych typov objektov. Pre jednoduché vytváranie objektov bez potreby hierarchie tovární.
Fabrika metóda Rozhranie na vytváranie objektu, umožňuje podtriedam rozhodnúť, akú triedu inštancie vytvoriť. Keď trieda nemôže predpovedať typ objektov, ktoré má vytvoriť.
Abstraktná továreň Poskytuje rozhranie na tvorbu súvislých alebo závislých rodín objektov bez určenia ich konkrétnych tried. Keď systém musí byť nezávislý od spôsobu tvorby a prezentácie produktov.

Vzory továreň podporujú slabé prepojenie kódu a uľahčujú pridanie nových typov produktov bez zmeny klientského kódu.