Sobes.tech
Middle

Factory ნიმუშის შესახებ ისაუბრე.

sobes.tech AI

პასუხი AI-სგან

ფაბრიკა — ეს არის შექმნის დიზაინის ნიმუში, რომელიც უზრუნველყოფს საერთო ინტერფეისს ობიექტების შექმნისთვის სუპერკლასში, ხოლო ქვესპერკლასები შეიძლება შეცვალონ შექმნილი ობიექტების ტიპი.

  • სადაც მარტივი ფაბრიკა (Simple Factory): არ არის ნიმუში სუფთა ფორმით, უფრო იდეომა. კლასი, რომელსაც აქვს მეთოდი, რომელიც ქმნის ობიექტებს შემავალი პარამეტრების მიხედვით.

    package main
    
    import "fmt"
    
    type Product interface {
    	Use()
    }
    
    type ConcreteProductA struct{}
    
    func (p *ConcreteProductA) Use() {
    	fmt.Println("Using Concrete Product A")
    }
    
    type ConcreteProductB struct{}
    
    func (p *ConcreteProductB) Use() {
    	fmt.Println("Using 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 "Result of the ConcreteProduct1"
    }
    
    // კონკრეტული პროდუქტი B
    type ConcreteProduct2 struct{}
    
    func (p *ConcreteProduct2) Operation() string {
    	return "Result of the ConcreteProduct2"
    }
    
    // შემქმნელის ინტერფეისი
    type Creator interface {
    	FactoryMethod() Product
    	SomeOperation() string
    }
    
    // ბაზის შემქმნელი
    type BaseCreator struct{}
    
    func (bc *BaseCreator) SomeOperation() string {
    	// გამოძახება ფაბრიკის მეთოდისთვის ობიექტის მიღებისთვის
    	product := bc.FactoryMethod()
    	// პროდუქტის გამოყენება
    	result := "Creator: The same creator's code has just worked with " + 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 "The result of the product A1."
    }
    
    // კონკრეტული პროდუქტი A2
    type ConcreteProductA2 struct{}
    
    func (*ConcreteProductA2) UseProductA() string {
    	return "The result of the product A2."
    }
    
    // პროდუქტის B ინტერფეისი
    type AbstractProductB interface {
    	UseProductB() string
    	AnotherFunctionB(collaborator AbstractProductA) string // ურთიერთქმედება პროდუქტის A-სთან
    }
    
    // კონკრეტული პროდუქტი B1
    type ConcreteProductB1 struct{}
    
    func (*ConcreteProductB1) UseProductB() string {
    	return "The result of the product B1."
    }
    
    // B1-ის ურთიერთქმედება ნებისმიერ AbstractProductA ტიპთან
    func (*ConcreteProductB1) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("The result of the B1 collaborating with the (%s)", result)
    }
    
    // კონკრეტული პროდუქტი B2
    type ConcreteProductB2 struct{}
    
    func (*ConcreteProductB2) UseProductB() string {
    	return "The result of the product B2."
    }
    
    // B2-ის ურთიერთქმედება ნებისმიერ AbstractProductA ტიპთან
    func (*ConcreteProductB2) AnotherFunctionB(collaborator AbstractProductA) string {
    	result := collaborator.UseProductA()
    	return fmt.Sprintf("The result of the B2 collaborating with the (%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{})
    }
    
    

მთავარი განსხვავება ფაბრიკის მეთოდსა და აბსტრაქტულ ფაბრიკას შორის: ფაბრიკის მეთოდი ქმნის ცალკეულ პროდუქტებს, მაშინ როცა აბსტრაქტული ფაბრიკა ქმნის პროდუქტების ოჯახებს.

ნიმუშის სახელი აღწერა როდის გამოიყენოთ
მარტივი ფაბრიკა მეთოდი ერთ კლასში სხვადასხვა ტიპის ობიექტების შესაქმნელად. მარტივი ობიექტების შექმნისთვის, როდესაც ფაბრიკის ჰიერქია საჭირო არაა.
ფაბრიკის მეთოდი ინტერფეისი ობიექტის შექმნისთვის, რომელიც საშუალებას აძლევს ქვესპერკლასებს გადაწყვიტონ, რომელი კლასი უნდა ინსტანცირდეს. როდესაც კლასი ვერ განსაზღვრავს, რომელი ტიპის ობიექტი უნდა შექმნას.
აბსტრაქტული ფაბრიკა ინტერფეისი დაკავშირებული ან დამოკიდებული ობიექტების ოჯახების შექმნისთვის. როდესაც სისტემამ უნდა იყოს დამოუკიდებელი მისი პროდუქტების შექმნის მეთოდიდან.

ფაბრიკის ნიმუში ხელს უწყობს კოდის სუსტი კავშირების შენარჩუნებას და ადვილად აძლიერებს ახალი ტიპის პროდუქტების დამატებას, გარეშე კლიენტის კოდის შეცვლას.