Sobes.tech
Junior

Z jakimi wzorcami projektowymi jesteś zaznajomiony?

sobes.tech AI

Odpowiedź od AI

Znam różne wzorce projektowe używane w Go. Niektóre z najczęstszych:

Wzorce kreacyjne:

  • Singleton: Zapewnia, że istnieje tylko jedna instancja klasy i udostępnia globalny punkt dostępu do niej. W Go często implementuje się to za pomocą sync.Once.
    package main
    
    import (
    	"sync"
    )
    
    type singleton struct{}
    
    var instance *singleton
    var once sync.Once
    
    func GetInstance() *singleton {
    	once.Do(func() {
    		instance = &singleton{}
    	})
    	return instance
    }
    
  • Factory Method: Definiuje interfejs do tworzenia obiektu, ale pozwala podklasom decydować, którą klasę zainstancjonować. W Go często realizuje się to za pomocą funkcji zwracających interfejs.
    package main
    
    type Product interface {
    	Operate()
    }
    
    type ConcreteProductA struct{}
    
    func (p *ConcreteProductA) Operate() {
    	// Implementacja operacji
    }
    
    type ConcreteProductB struct{}
    
    func (p *ConcreteProductB) Operate() {
    	// Implementacja operacji
    }
    
    func NewProduct(productType string) Product {
    	switch productType {
    	case "A":
    		return &ConcreteProductA{}
    	case "B":
    		return &ConcreteProductB{}
    	default:
    		return nil // lub błąd
    	}
    }
    
  • Abstract Factory: Udostępnia interfejs do tworzenia rodzin powiązanych lub zależnych obiektów bez określania ich konkretnych klas.
  • Builder: Oddziela proces konstruowania złożonego obiektu od jego reprezentacji.

Wzorce strukturalne:

  • Adapter: Konwertuje interfejs jednej klasy na inny, wymagany przez klientów. Umożliwia współpracę niekompatybilnych klas.
  • Decorator: Dynamicznie dodaje nowe obowiązki obiektowi. Dekoratory zapewniają elastyczną alternatywę dla dziedziczenia w celu rozszerzenia funkcjonalności.
  • Facade: Udostępnia zunifikowany interfejs do zestawu interfejsów w podsystemie. Definiuje interfejs wysokiego poziomu, który ułatwia korzystanie z podsystemu.
  • Proxy: Udostępnia zamiennik lub reprezentację dla innego obiektu w celu zarządzania dostępem do niego.

Wzorce behawioralne:

  • Observer: Definiuje zależność "jeden do wielu" między obiektami. Gdy stan obiektu się zmienia, wszystkie jego zależne obiekty są powiadamiane i automatycznie aktualizowane.
  • Strategy: Definiuje rodzinę algorytmów, kapsułkuje każdy z nich i czyni je wymienialnymi. Umożliwia zmianę algorytmów niezależnie od klientów ich używających.
    package main
    
    type Strategy interface {
    	Execute(data string)
    }
    
    type ConcreteStrategyA struct{}
    
    func (s *ConcreteStrategyA) Execute(data string) {
    	// Implementacja strategii A
    }
    
    type ConcreteStrategyB struct{}
    
    func (s *ConcreteStrategyB) Execute(data string) {
    	// Implementacja strategii B
    }
    
    type Context struct {
    	strategy Strategy
    }
    
    func (c *Context) SetStrategy(strategy Strategy) {
    	c.strategy = strategy
    }
    
    func (c *Context) ExecuteStrategy(data string) {
    	c.strategy.Execute(data)
    }
    
  • Template Method: Definiuje szkielet algorytmu w operacji, pozostawiając niektóre kroki podklasom. Pozwala podklasom redefiniować niektóre kroki algorytmu bez zmiany jego struktury.

Poza wymienionymi wzorcami, znam także Command, Chain of Responsibility, Iterator, Mediator, Memento, State, Visitor. W Go często używa się także idiomów projektowych specyficznych dla języka, takich jak użycie interfejsów do abstrakcji, gorutyn i kanałów do równoległości.