2024 #30: Quality & SOLID design
We have been talking a lot around the architecture of our application at Print.com.
-
https://dave.cheney.net/2016/08/20/solid-go-design Dave makes the SOLID principles directly applicable to Go. It’s easy to forget the principles when your deep into it.
Look at code reviews for:
- Rigid. Is the code rigid? Does it have a straight jacket of overbearing types and parameters, that making modification difficult?
- Fragile. Is the code fragile? Does the slightest change ripple through the code base causing untold havoc?
- Immobile. Is the code hard to refactor? Is it one keystroke away from an import loop?
- Complex. Is there code for the sake of having code, are things over-engineered?
- Verbose. Is it just exhausting to use the code? When you look at it, can you even tell what this code is trying to do? But these are negative terms. How can we describe what “good” is? We come back to the SOLID principles.
Single Responsibility Principle (SRP): Code should have one responsibility so that it has fewer reasons to change.
- Coupling: a movement in one induces a movement in another.
- Cohesion: the pieces of code that are attracted to each other.
Packages like utils or common often become a dumping ground for code and thus change often. Purely, in Unix philosohy, a package has a single responsibility and is in itself a small Go application.
Open/Closed Principle (OCP): It should be easy to extend functionality without modifying existing code. This principle is explained a bit worse. Have to read up a bit on embedding and when it is appropriate. (https://go.dev/doc/effective_go#embedding) Liskov Substitution Principle (LSP): An implementation of an interface should be substitutable for another implementation. The whole hexagonal architecture is based on this principle. Interface Segregation Principle (ISP): Dependency Inversion Principle (DIP):