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.