SOLID in Go
SOLID Principles in Go
SOLID is often associated with Java/OOP. However, its core principles (decoupling, cohesion) apply perfectly to Go, just implemented differently.
S: Single Responsibility Principle (SRP)
“A package should have one reason to change.”
Go enforces this with its package system. * Bad: package utils (The junk drawer). * Good: package hash, package user, package http.
O: Open/Closed Principle
“Open for extension, closed for modification.”
In Go, we achieve this via Interfaces. If a function accepts an interface, you can extend its behavior by passing a new struct that satisfies the interface, without modifying the function.
type Shape interface { Area() float64 }
func TotalArea(shapes []Shape) float64 {
var total float64
for _, s := range shapes {
total += s.Area()
}
return total
}You can add Triangle later without touching TotalArea.
L: Liskov Substitution Principle
“Subtypes must be substitutable for their base types.”
In Go, this is implicit. If *MyWriter satisfies io.Writer, it is an io.Writer. However, you must ensure behavioral compatibility (e.g., don’t panic in a Write method).
I: Interface Segregation Principle
“Clients should not be forced to depend on methods they do not use.”
This is the most important rule in Go. * Java: Define big interfaces upfront (IUser). * Go: Define tiny interfaces where you use them.
Bad:
type User interface {
Save()
Delete()
SendEmail()
Validate()
}
func Emailer(u User) { ... } // Forces dependence on Save/DeleteGood:
type EmailSender interface {
SendEmail()
}
func Emailer(e EmailSender) { ... } // Only depends on what it needsD: Dependency Inversion Principle
“Depend on abstractions, not concretions.”
Don’t accept structs; accept interfaces.
Bad:
func NewService(db *sql.DB) // ConcretionGood:
type Datastore interface {
Query(string) Rows
}
func NewService(db Datastore) // AbstractionThis allows you to swap sql.DB for a Mock DB during testing.
Summary
SOLID in Go is simpler than in OOP. * S: Small packages. * O / D: Accept interfaces, return structs. * I: Define 1-method interfaces locally.