Sobes.tech
Junior

Com quais padrões de design você está familiarizado?

sobes.tech IA

Resposta da IA

Estou familiarizado com vários padrões de projeto utilizados em Go. Alguns dos mais comuns:

Padrões criacionais:

  • Singleton: Garante que apenas uma instância de uma classe exista e fornece um ponto de acesso global a ela. Em Go, frequentemente é implementado usando 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: Define uma interface para criar um objeto, mas permite às subclasses decidir qual classe instanciar. Em Go, frequentemente é implementado usando funções que retornam interfaces.
    package main
    
    type Product interface {
    	Operate()
    }
    
    type ConcreteProductA struct{}
    
    func (p *ConcreteProductA) Operate() {
    	// Implementação da operação
    }
    
    type ConcreteProductB struct{}
    
    func (p *ConcreteProductB) Operate() {
    	// Implementação da operação
    }
    
    func NewProduct(productType string) Product {
    	switch productType {
    	case "A":
    		return &ConcreteProductA{}
    	case "B":
    		return &ConcreteProductB{}
    	default:
    		return nil // Ou erro
    	}
    }
    
  • Abstract Factory: Fornece uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
  • Builder: Separa o processo de construção de um objeto complexo de sua representação.

Padrões estruturais:

  • Adapter: Converte a interface de uma classe em outra que os clientes esperam. Permite que classes incompatíveis trabalhem juntas.
  • Decorator: Adiciona responsabilidades adicionais a um objeto dinamicamente. Decoradores oferecem uma alternativa flexível à herança para estender funcionalidades.
  • Facade: Fornece uma interface unificada a um conjunto de interfaces em um subsistema. Define uma interface de alto nível que facilita o uso do subsistema.
  • Proxy: Fornece um substituto ou representante para outro objeto para controlar o acesso a ele.

Padrões comportamentais:

  • Observer: Define uma dependência de "um para muitos" entre objetos. Quando um objeto muda seu estado, todos os seus dependentes são notificados e atualizados automaticamente.
  • Strategy: Define uma família de algoritmos, encapsula cada um e os torna intercambiáveis. Permite que os algoritmos variem independentemente dos clientes que os utilizam.
    package main
    
    type Strategy interface {
    	Execute(data string)
    }
    
    type ConcreteStrategyA struct{}
    
    func (s *ConcreteStrategyA) Execute(data string) {
    	// Implementação da estratégia A
    }
    
    type ConcreteStrategyB struct{}
    
    func (s *ConcreteStrategyB) Execute(data string) {
    	// Implementação da estratégia 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: Define o esqueleto de um algoritmo em uma operação, deixando alguns passos para as subclasses. Permite que as subclasses redefinam certos passos de um algoritmo sem alterar sua estrutura.

Além dos padrões mencionados, também conheço padrões como Command, Chain of Responsibility, Iterator, Mediator, Memento, State, Visitor. Em Go, também se usam frequentemente idioms de projeto específicos da linguagem, como o uso de interfaces para abstração, goroutines e canais para concorrência.