Go:
Refatoração
Como Fazer:
Em Go, a refatoração pode variar de ajustes simples no código a mudanças mais complexas. Vamos começar com um exemplo básico: simplificar uma função inicial em Go para melhor legibilidade e eficiência.
Antes da Refatoração:
package main
import "fmt"
func CalculatePrice(quantity int, price float64) float64 {
var total float64
if quantity > 0 {
total = float64(quantity) * price
} else {
total = 0
}
return total
}
func main() {
fmt.Println(CalculatePrice(10, 5.99)) // Saída: 59.9
}
Após Refatoração:
package main
import "fmt"
func CalculatePrice(quantity int, price float64) float64 {
if quantity > 0 {
return float64(quantity) * price
}
return 0
}
func main() {
fmt.Println(CalculatePrice(10, 5.99)) // Saída: 59.9
}
Na versão refatorada, else
é removido, o que simplifica o fluxo da função sem afetar seu resultado — um exemplo de uma técnica de refatoração básica, mas impactante, em Go.
Para um exemplo mais avançado, considere refatorar funções para usar interfaces, visando uma melhor reusabilidade e testabilidade:
Antes da Refatoração:
package main
import "fmt"
type Logger struct{}
func (l Logger) Log(message string) {
fmt.Println("Log:", message)
}
func ProcessData(data string, logger Logger) {
// Imagine algum processamento de dados aqui
logger.Log("Dados processados")
}
func main() {
logger := Logger{}
ProcessData("dados de exemplo", logger)
}
Após Refatoração:
package main
import "fmt"
type Logger interface {
Log(message string)
}
type ConsoleLogger struct{}
func (c ConsoleLogger) Log(message string) {
fmt.Println("Log:", message)
}
func ProcessData(data string, logger Logger) {
// O processamento de dados permanece inalterado
logger.Log("Dados processados")
}
func main() {
logger := ConsoleLogger{}
ProcessData("dados de exemplo", logger)
}
Refatorar para usar uma interface (Logger
) em vez de um tipo concreto (ConsoleLogger
) melhora a flexibilidade da função e desacopla o processamento de dados da implementação específica de log.
Aprofundamento
Refatorar em Go deve equilibrar simplicidade (uma das filosofias centrais do Go) com a flexibilidade necessária em grandes projetos de software. Dado a abordagem minimalista do Go para recursos — sem genéricos (até recentemente) e com forte ênfase na legibilidade — a linguagem naturalmente guia os desenvolvedores para estruturas de código mais simples e mais mantentáveis. No entanto, isso não significa que o código Go não se beneficie da refatoração; significa que a refatoração deve sempre priorizar clareza e simplicidade.
Historicamente, a falta de certos recursos no Go (por exemplo, genéricos antes do Go 1.18) levou a soluções criativas, mas às vezes complicadas, para reutilização de código e flexibilidade, tornando a refatoração para abstração uma prática comum. Com a introdução de genéricos no Go 1.18, os desenvolvedores de Go estão agora refatorando o código legado para aproveitar esse recurso para uma melhor segurança de tipos e reutilização de código, demonstrando a natureza evolutiva das práticas de refatoração em Go.
No entanto, o conjunto de ferramentas do Go, incluindo gofmt
para formatação de código e go vet
para identificar construções suspeitas, suporta a manutenção de bases de código limpas, reduzindo a necessidade de refatorações extensivas. Embora a refatoração seja uma ferramenta inestimável no arsenal de um programador Go, o uso sábio das funcionalidades da linguagem e das ferramentas desde o início pode ajudar a minimizar a necessidade de refatorações complexas mais tarde.