Sobes.tech
Middle

Räägi Factory mustrist.

sobes.tech AI

Vastus AI-lt

Töötuba on loomise muster, mis pakub üldist liidest objektide loomisel superklassis, samas kui alamklassid võivad muuta loodavate objektide tüüpi.

  • Lihtne tehas (Simple Factory): ei ole puhas muster, pigem idiom. Klass koos meetodiga, mis loob objekte sisendparameetrite põhjal.

    package main
    
    import "fmt"
    
    type Product interface {
    	Use()
    }
    
    type ConcreteProductA struct{}
    
    func (p *ConcreteProductA) Use() {
    	fmt.Println("Kasutades konkreetset toodet A")
    }
    
    type ConcreteProductB struct{}
    
    func (p *ConcreteProductB) Use() {
    	fmt.Println("Kasutades konkreetset toodet 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()
    }
    
  • Tehase meetod (Factory Method): määratleb liidese objekti loomise jaoks, kuid võimaldab alamklassidel otsustada, millist klassi instantsida.

    package main
    
    import "fmt"
    
    // Toote liides
    type Product interface {
    	Operation() string
    }
    
    // Konkreetne toode A
    type ConcreteProduct1 struct{}
    
    func (p *ConcreteProduct1) Operation() string {
    	return "Tulemus ConcreteProduct1-st"
    }
    
    // Konkreetne toode B
    type ConcreteProduct2 struct{}
    
    func (p *ConcreteProduct2) Operation() string {
    	return "Tulemus ConcreteProduct2-st"
    }
    
    // Looja liides
    type Creator interface {
    	FactoryMethod() Product
    	SomeOperation() string
    }
    
    // Põhiline looja
    type BaseCreator struct{}
    
    func (bc *BaseCreator) SomeOperation() string {
    	// Kutsume tehase meetodi, et saada toote objekt
    	product := bc.FactoryMethod()
    	// Kasutame toodet
    	result := "Looja: sama kood töötas just koos " + product.Operation()
    	return result
    }
    
    // Konkreetne looja A
    type ConcreteCreator1 struct {
    	BaseCreator
    }
    
    func (cc *ConcreteCreator1) FactoryMethod() Product {
    	return &ConcreteProduct1{} // Loob konkreetse toote A
    }
    
    // Konkreetne looja B
    type ConcreteCreator2 struct {
    	BaseCreator
    }
    
    func (cc *ConcreteCreator2) FactoryMethod() Product {
    	return &ConcreteProduct2{} // Loob konkreetse toote B
    }
    
    func main() {
    	// Kasutuse näide
    	creator1 := &ConcreteCreator1{}
    	fmt.Println(creator1.SomeOperation())
    
    	creator2 := &ConcreteCreator2{}
    	fmt.Println(creator2.SomeOperation())
    }
    
    
  • Klassikaline tehas (Abstract Factory): pakub liidest seotud või sõltuvate objektide perekondade loomisel ilma nende konkreetsete klassideta.

    package main
    
    import "fmt"
    
    // Toote A liides
    type AbstractProductA interface {
    	UseProductA() string
    }
    
    // Konkreetne toode A1
    type ConcreteProductA1 struct{}
    
    func (*ConcreteProductA1) UseProductA() string {
    	return "A1 toote tulemus."
    }
    
    // Konkreetne toode A2
    type ConcreteProductA2 struct{}
    
    func (*ConcreteProductA2) UseProductA() string {
    	return "A2 toote tulemus."
    }
    
    // Toote B liides
    type AbstractProductB interface {
    	UseProductB() string
    	AnotherFunctionB(collaborator AbstractProductA) string // koostöö toote A-ga
    }
    
    // Konkreetne toode B1
    type ConcreteProductB1 struct{}
    
    func (*ConcreteProductB1) UseProductB() string {
    	return "B1 toote tulemus."
    }
    
    // B1 koostöö mis tahes AbstractProductA tüüpi
    func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("B1 koostöö (%s)"
    }
    
    // Konkreetne toode B2
    type ConcreteProductB2 struct{}
    
    func (*ConcreteProductB2) UseProductB() string {
    	return "B2 toote tulemus."
    }
    
    // B2 koostöö mis tahes AbstractProductA tüüpi
    func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("B2 koostöö (%s)"
    }
    
    // Abstraktse tehase liides
    type AbstractFactory interface {
    	CreateProductA() AbstractProductA
    	CreateProductB() AbstractProductB
    }
    
    // Konkreetne tehas 1
    type ConcreteFactory1 struct{}
    
    func (*ConcreteFactory1) CreateProductA() AbstractProductA {
    	return &ConcreteProductA1{}
    }
    
    func (*ConcreteFactory1) CreateProductB() AbstractProductB {
    	return &ConcreteProductB1{}
    }
    
    // Konkreetne tehas 2
    type ConcreteFactory2 struct{}
    
    func (*ConcreteFactory2) CreateProductA() AbstractProductA {
    	return &ConcreteProductA2{}
    }
    
    func (*ConcreteFactory2) CreateProductB() AbstractProductB {
    	return &ConcreteProductB2{}
    }
    
    // Kliendi kood, mis töötab tehasega
    func ClientCode(factory AbstractFactory) {
    	productA := factory.CreateProductA()
    	productB := factory.CreateProductB()
    
    	fmt.Println(productB.UseProductB())
    	fmt.Println(productB.AnotherFunctionB(productA))
    }
    
    func main() {
    	fmt.Println("Kliendi testimine esimese tehase tüüpi:")
    	ClientCode(&ConcreteFactory1{})
    
    	fmt.Println("Kliendi testimine teise tehase tüüpi:")
    	ClientCode(&ConcreteFactory2{})
    }
    
    

Peamine erinevus Fabrika meetodi ja Abstraktse tehase vahel: Fabrika meetod loob üksiktooteid, samas kui Abstraktne tehas loob toote perekondi.

Muster nimi Kirjeldus Kui kasutada
Lihtne tehas Meetod ühes klassis erinevat tüüpi objektide loomiseks. Lihtsate objektide loomisel, kui hierarhia ei ole vajalik.
Fabrika meetod Liides objekti loomiseks, mis võimaldab alamklassidel otsustada, millist klassi instancseerida. Kui klass ei suuda ette näha, millist tüüpi objekte ta peab looma.
Abstraktne tehas Liides seotud või sõltuvate objektide perekondade loomiseks. Kui süsteem peab olema sõltumatu selle loomise viisist.

Fabrika muster soodustab koodi nõrka sidumist ja lihtsustab uute toote tüüpide lisamist ilma kliendi koodi muutmata.