But why care about SOLID?

Or: Why care about any Software Engineering principles? Embracing principles makes you a more adaptable engineer. You’re no longer tied to a specific framework, language, or tech stack. Instead, you can work effectively with the tools at hand and make them work for you. For example, I appreciate the SOLID principles. When I have the freedom to choose, and it fits the project, I often reach for Kotlin. It makes applying core principles straightforward in most cases. SOLID Principles in Kotlin // Single Responsibility Principle class ReportGenerator { fun generate() { /* ... */ } } class ReportPrinter { fun print(report: ReportGenerator) { /* ... */ } } // Open/Closed Principle open class Shape { open fun area(): Double = 0.0 } class Circle(val radius: Double) : Shape() { override fun area() = Math.PI * radius * radius } // Liskov Substitution Principle open class Bird { open fun fly() = "Flying" } class Sparrow : Bird() class Ostrich : Bird() { override fun fly() = throw UnsupportedOperationException() } // Interface Segregation Principle interface Printer { fun print() } interface Scanner { fun scan() } class MultiFunctionPrinter : Printer, Scanner { /* ... */ } // Dependency Inversion Principle interface Engine { fun start() } class Car(private val engine: Engine) { fun drive() = engine.start() } But what if I need to use something else, like Go? The specific language isn’t the most important thing. As long as the problem is solvable with the available tools, what matters is that they support the principles that guide your work. I care about the mission and delivering value, not unnecessary complexity or academic perfection. My goal is to leave codebases better than I found them—clear, maintainable, and kind to those who come after me. That’s our responsibility as software engineers. Software engineering principles and design patterns popularized by leaders in our industry exist for a reason. They’ve done the hard work and generously shared their insights. Why not stand on the shoulders of giants? Some giants to thank: Gang of Four (Design Patterns book) Martin Fowler Eric Evans (Domain-Driven Design) Robert C. Martin (Uncle Bob) (SOLID) Here are those same SOLID principles, but in Go—this time, using functional types where it makes sense: // Single Responsibility Principle type ReportGenerator func() string type ReportPrinter func(report string) func generateReport() string { return "report" } func printReport(report string) { /* ... */ } // Open/Closed Principle type Shape interface { Area() float64 } type Circle struct { Radius float64 } func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius } // Liskov Substitution Principle type Bird interface { Fly() string } type Sparrow struct{} func (s Sparrow) Fly() string { return "Flying" } type Ostrich struct{} func (o Ostrich) Fly() string { panic("can't fly") } // Interface Segregation Principle type Printer interface { Print() } type Scanner interface { Scan() } type MultiFunctionPrinter struct{} func (m MultiFunctionPrinter) Print() { /* ... */ } func (m MultiFunctionPrinter) Scan() { /* ... */ } // Dependency Inversion Principle type Engine func() error type Car struct { engine Engine } func (c Car) Drive() error { return c.engine() } At first glance, the code looks different. Naturally—it’s a different language with its own syntax and idioms. But the underlying principles remain the same, unlocking the same benefits in your codebase. That’s why it’s always worthwhile to learn the features of the language you’re working in. My guiding steps: Make it work Make it right Make it better I encourage you: Find ideals and principles that you and your team can support. Then, be open to what that might mean for your code. It may involve using language features that are unfamiliar at first. But if it leaves your codebase easier to maintain, more readable, better tested, more modular, or more aligned with the ubiquitous language of your domain—embrace it! You’ll be improving yourself, your team, and your product. And if you care about the people for whom you're building, that should be motivation enough. Thanks for reading! ✌️

May 9, 2025 - 18:23
 0
But why care about SOLID?

Or: Why care about any Software Engineering principles?

Embracing principles makes you a more adaptable engineer. You’re no longer tied to a specific framework, language, or tech stack. Instead, you can work effectively with the tools at hand and make them work for you.

For example, I appreciate the SOLID principles. When I have the freedom to choose, and it fits the project, I often reach for Kotlin. It makes applying core principles straightforward in most cases.

SOLID Principles in Kotlin

// Single Responsibility Principle
class ReportGenerator {
    fun generate() { /* ... */ }
}
class ReportPrinter {
    fun print(report: ReportGenerator) { /* ... */ }
}

// Open/Closed Principle
open class Shape { open fun area(): Double = 0.0 }
class Circle(val radius: Double) : Shape() {
    override fun area() = Math.PI * radius * radius
}

// Liskov Substitution Principle
open class Bird { open fun fly() = "Flying" }
class Sparrow : Bird()
class Ostrich : Bird() { override fun fly() = throw UnsupportedOperationException() }

// Interface Segregation Principle
interface Printer { fun print() }
interface Scanner { fun scan() }
class MultiFunctionPrinter : Printer, Scanner { /* ... */ }

// Dependency Inversion Principle
interface Engine { fun start() }
class Car(private val engine: Engine) { fun drive() = engine.start() }

But what if I need to use something else, like Go? The specific language isn’t the most important thing. As long as the problem is solvable with the available tools, what matters is that they support the principles that guide your work.

I care about the mission and delivering value, not unnecessary complexity or academic perfection. My goal is to leave codebases better than I found them—clear, maintainable, and kind to those who come after me. That’s our responsibility as software engineers.

Software engineering principles and design patterns popularized by leaders in our industry exist for a reason. They’ve done the hard work and generously shared their insights. Why not stand on the shoulders of giants?

Some giants to thank:

Here are those same SOLID principles, but in Go—this time, using functional types where it makes sense:

// Single Responsibility Principle
type ReportGenerator func() string
type ReportPrinter func(report string)

func generateReport() string { return "report" }
func printReport(report string) { /* ... */ }

// Open/Closed Principle
type Shape interface { Area() float64 }
type Circle struct { Radius float64 }
func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius }

// Liskov Substitution Principle
type Bird interface { Fly() string }
type Sparrow struct{}
func (s Sparrow) Fly() string { return "Flying" }
type Ostrich struct{}
func (o Ostrich) Fly() string { panic("can't fly") }

// Interface Segregation Principle
type Printer interface { Print() }
type Scanner interface { Scan() }
type MultiFunctionPrinter struct{}
func (m MultiFunctionPrinter) Print() { /* ... */ }
func (m MultiFunctionPrinter) Scan() { /* ... */ }

// Dependency Inversion Principle
type Engine func() error
type Car struct { engine Engine }
func (c Car) Drive() error { return c.engine() }

At first glance, the code looks different. Naturally—it’s a different language with its own syntax and idioms. But the underlying principles remain the same, unlocking the same benefits in your codebase. That’s why it’s always worthwhile to learn the features of the language you’re working in.

My guiding steps:

  1. Make it work
  2. Make it right
  3. Make it better

I encourage you: Find ideals and principles that you and your team can support. Then, be open to what that might mean for your code. It may involve using language features that are unfamiliar at first.

But if it leaves your codebase easier to maintain, more readable, better tested, more modular, or more aligned with the ubiquitous language of your domain—embrace it! You’ll be improving yourself, your team, and your product.

And if you care about the people for whom you're building, that should be motivation enough.

Thanks for reading! ✌️