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
}
|