Princípios SOLID em Go: teoria e prática em Golang

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Princípios SOLID em Go: teoria e prática



SOLID é um acrônimo de cinco princípios fundamentais de design orientado a objetos que ajudam a criar código flexível, sustentável e escalável. Embora Go não seja uma linguagem OOP clássica (não possui herança de classes), suas interfaces, composição e tipagem forte permitem aplicar SOLID com sucesso. Neste artigo, vamos analisar cada princípio com exemplos do mundo real em Go.



1. Princípio da Responsabilidade Única (SRP — Single Responsibility Principle)



Teoria: Cada tipo (struct, função, interface) deve ter apenas um motivo para mudar. Em outras palavras, ele é responsável por apenas uma parte da funcionalidade do programa.



Prática em Go: Um erro comum é criar structs "divinas" que lidam com lógica de negócios, logging e envio de notificações ao mesmo tempo.



Exemplo ruim (violação do SRP):



type OrderService struct{}

func (s *OrderService) Create(order Order) error { // 1. Salvar no banco de dados // 2. Enviar email // 3. Logging return nil}


Exemplo bom (respeitando o SRP):



type OrderRepository interface {    Save(order Order) error}

type EmailService interface { Send(to string, subject string, body string) error}

type Logger interface { Info(msg string)}

type OrderService struct { repo OrderRepository email EmailService log Logger}

func (s *OrderService) Create(order Order) error { if err := s.repo.Save(order); err != nil { s.log.Info("Failed to save order") return err } if err := s.email.Send(order.Email, "Order Confirmed", "Your order is placed"); err != nil { s.log.Info("Failed to send email") } s.log.Info("Order created successfully") return nil}


Agora cada struct é responsável apenas por sua tarefa, e alterar a lógica do email não afetará o salvamento dos pedidos.



2. Princípio do Aberto/Fechado (OCP — Open/Closed Principle)



Teoria: Classes (tipos) devem estar abertas para extensão, mas fechadas para modificação. Ou seja, você deve ser capaz de adicionar nova funcionalidade sem alterar o código existente.



Prática em Go: Use interfaces e composição para adicionar novas implementações sem alterar a lógica principal.



Exemplo: Suponha que temos um sistema de cálculo de custo de frete. Inicialmente, existe apenas "frete padrão", mas precisamos adicionar "frete expresso".



// Definindo a interfacetype ShippingCostCalculator interface {    Calculate(order Order) float64}

// Implementação padrãotype StandardShipping struct{}

func (s StandardShipping) Calculate(order Order) float64 { return 5.99}

// Nova implementação sem alterar o código acimatype ExpressShipping struct{}

func (e ExpressShipping) Calculate(order Order) float64 { return 15.99}

// Usofunc ProcessOrder(order Order, calculator ShippingCostCalculator) { cost := calculator.Calculate(order) fmt.Printf("Shipping cost: %.2f", cost)}


Não alteramos ProcessOrder — apenas passamos uma nova instância de ExpressShipping. Isso é o OCP.



3. Princípio da Substituição de Liskov (LSP — Liskov Substitution Principle)



Teoria: Objetos em um programa devem ser substituíveis por instâncias de seus subtipos sem alterar a correção do programa. Em Go, isso significa que se uma função espera uma interface, qualquer implementação dessa interface deve funcionar corretamente.



Prática em Go: Certifique-se de que suas implementações de interface não violem as expectativas do código chamador. Por exemplo, se a interface pressupõe que o método GetName() sempre retorna

Blogs

Book Recommendations