Featured image of post SOLID in a Nutshell

SOLID in a Nutshell

Code examples in Go and Rust

SOLID in Go and Rust: A Pragmatic Approach to Clean Code

The SOLID Principles in Go and Rust

1. Single Responsibility Principle (SRP)

One job per struct, please.

Bad Example (Go):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

type Report struct {}

func (r Report) Generate() {
    // Generate report
}

func (r Report) SaveToFile() {
    // Save report to file
}

The Report struct is doing too much. Let’s split it up.

Good Example (Go):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package main

type ReportGenerator struct {}

func (r ReportGenerator) Generate() {
    // Generate report
}

type ReportSaver struct {}

func (r ReportSaver) Save(report ReportGenerator) {
    // Save to file
}

Now, each struct has its own responsibility. Much better!

Bad Example (Rust):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
struct Report;

impl Report {
    fn generate(&self) {
        // Generate report
    }
    fn save_to_file(&self) {
        // Save report
    }
}

Good Example (Rust):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
struct ReportGenerator;

impl ReportGenerator {
    fn generate(&self) {
        // Generate report
    }
}

struct ReportSaver;

impl ReportSaver {
    fn save(&self, report: &ReportGenerator) {
        // Save report
    }
}

Separation of concerns FTW!


2. Open/Closed Principle (OCP)

A struct should be open for extension, but closed for modification.

Bad Example (Go):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

type DiscountService struct {}

func (d DiscountService) Apply(price float64, discountType string) float64 {
    if discountType == "Christmas" {
        return price * 0.9
    } else if discountType == "BlackFriday" {
        return price * 0.8
    }
    return price
}