Sobes.tech
Middle

Papaskink apie Factory šabloną.

sobes.tech AI

Atsakymas iš AI

Gamykla — tai kūrimo dizaino šablonas, kuris teikia bendrą sąsają objektų kūrimui superklase, o pogrupiai gali keisti kuriamų objektų tipą.

  • Paprasta gamykla (Simple Factory): nėra grynas šablonas, labiau idioma. Klasė su metodu, kuris kuria objektus pagal įvestus parametrus.

    package main
    
    import "fmt"
    
    type Product interface {
    	Use()
    }
    
    type ConcreteProductA struct{}
    
    func (p *ConcreteProductA) Use() {
    	fmt.Println("Naudojama konkretus produktas A")
    }
    
    type ConcreteProductB struct{}
    
    func (p *ConcreteProductB) Use() {
    	fmt.Println("Naudojama konkretus produktas 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()
    }
    
  • Fabriko metodas (Factory Method): apibrėžia sąsają objektų kūrimui, bet leidžia pogrupiams nuspręsti, kurį klasės egzempliorių kurti.

    package main
    
    import "fmt"
    
    // Produkto sąsaja
    type Product interface {
    	Operation() string
    }
    
    // Konkretaus produkto A
    type ConcreteProduct1 struct{}
    
    func (p *ConcreteProduct1) Operation() string {
    	return "ConcreteProduct1 rezultatas"
    }
    
    // Konkretaus produkto B
    type ConcreteProduct2 struct{}
    
    func (p *ConcreteProduct2) Operation() string {
    	return "ConcreteProduct2 rezultatas"
    }
    
    // Kūrėjo sąsaja
    type Creator interface {
    	FactoryMethod() Product
    	SomeOperation() string
    }
    
    // Bazinis kūrėjas
    type BaseCreator struct{}
    
    func (bc *BaseCreator) SomeOperation() string {
    	// Iškviečia fabriko metodą, kad gautų produkto objektą
    	product := bc.FactoryMethod()
    	// Naudoja produktą
    	result := "Kūrėjas: tas pats kodo naudojimas su " + product.Operation()
    	return result
    }
    
    // Konkretaus kūrėjo A
    type ConcreteCreator1 struct {
    	BaseCreator
    }
    
    func (cc *ConcreteCreator1) FactoryMethod() Product {
    	return &ConcreteProduct1{} // Kuria konkretų produktą A
    }
    
    // Konkretaus kūrėjo B
    type ConcreteCreator2 struct {
    	BaseCreator
    }
    
    func (cc *ConcreteCreator2) FactoryMethod() Product {
    	return &ConcreteProduct2{} // Kuria konkretų produktą B
    }
    
    func main() {
    	// Pavyzdys naudojimo
    	creator1 := &ConcreteCreator1{}
    	fmt.Println(creator1.SomeOperation())
    
    	creator2 := &ConcreteCreator2{}
    	fmt.Println(creator2.SomeOperation())
    }
    
    
  • Abstrakti gamykla (Abstract Factory): teikia sąsają kurti susijusių arba priklausomų objektų šeimas be jų konkrečių klasių nurodymo.

    package main
    
    import "fmt"
    
    // Produkto A sąsaja
    type AbstractProductA interface {
    	UseProductA() string
    }
    
    // Konkretaus produkto A1
    type ConcreteProductA1 struct{}
    
    func (*ConcreteProductA1) UseProductA() string {
    	return "A produktas A1 rezultatas."
    }
    
    // Konkretaus produkto A2
    type ConcreteProductA2 struct{}
    
    func (*ConcreteProductA2) UseProductA() string {
    	return "A produktas A2 rezultatas."
    }
    
    // Produkto B sąsaja
    type AbstractProductB interface {
    	UseProductB() string
    	AnotherFunctionB(collaborator AbstractProductA) string // sąveika su produktu A
    }
    
    // Konkretaus produkto B1
    type ConcreteProductB1 struct{}
    
    func (*ConcreteProductB1) UseProductB() string {
    	return "B produkto B1 rezultatas."
    }
    
    // B1 sąveika su bet kokiu AbstractProductA tipu
    func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("B1 bendradarbiavimas su (%s)", result)
    }
    
    // Konkretaus produkto B2
    type ConcreteProductB2 struct{}
    
    func (*ConcreteProductB2) UseProductB() string {
    	return "B produkto B2 rezultatas."
    }
    
    // B2 sąveika su bet kokiu AbstractProductA tipu
    func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("B2 bendradarbiavimas su (%s)", result)
    }
    
    // Abstrakčios gamyklos sąsaja
    type AbstractFactory interface {
    	CreateProductA() AbstractProductA
    	CreateProductB() AbstractProductB
    }
    
    // Konkreti gamykla 1
    type ConcreteFactory1 struct{}
    
    func (*ConcreteFactory1) CreateProductA() AbstractProductA {
    	return &ConcreteProductA1{}
    }
    
    func (*ConcreteFactory1) CreateProductB() AbstractProductB {
    	return &ConcreteProductB1{}
    }
    
    // Konkreti gamykla 2
    type ConcreteFactory2 struct{}
    
    func (*ConcreteFactory2) CreateProductA() AbstractProductA {
    	return &ConcreteProductA2{}
    }
    
    func (*ConcreteFactory2) CreateProductB() AbstractProductB {
    	return &ConcreteProductB2{}
    }
    
    // Kliento kodas, dirbantis su gamykla
    func ClientCode(factory AbstractFactory) {
    	productA := factory.CreateProductA()
    	productB := factory.CreateProductB()
    
    	fmt.Println(productB.UseProductB())
    	fmt.Println(productB.AnotherFunctionB(productA))
    }
    
    func main() {
    	fmt.Println("Kliento: Testuojame kliento kodą su pirmąja gamykla:")
    	ClientCode(&ConcreteFactory1{})
    
    	fmt.Println("Kliento: Testuojame tą patį kliento kodą su antrąja gamykla:")
    	ClientCode(&ConcreteFactory2{})
    }
    
    

Pagrindinis skirtumas tarp Fabriko metodo ir Abstrakčios gamyklos: Fabriko metodas kuria atskirus produktus, o Abstrakčioji gamykla kuria produktų šeimas.

Šablono pavadinimas Aprašymas Kada naudoti
Paprasta gamykla Metodas viename klase kurti skirtingų tipų objektus. Paprastam objektų kūrimui, kai nereikia hierarchijos.
Fabriko metodas Sąsaja objektų kūrimui, leidžianti pogrupiams nuspręsti, kurį klasės egzempliorių kurti. Kai klasė negali nuspėti, kokio tipo objektų turi kurti.
Abstrakti gamykla Sąsaja susijusių arba priklausomų objektų šeimų kūrimui. Kai sistema turi būti nepriklausoma nuo jos produktų kūrimo būdo.

Fabriko šablonas skatina silpną kodo sujungimą ir palengvina naujų produktų tipų pridėjimą be kliento kodo keitimo.