These are the principles I try to keep in the back of my mind when writing software.
Be pragmatic
Having a perfectly engineered solution is great, but sometimes itās okay to have a sub-optimal approach until it holds you back too much. Premature optimization is an obvious example of this.
Work incrementally
Donāt go straight for a full-blown solution that solves all problems. Start with the most basic case first to get a better understanding of the problem space.
Use abstractions
Abstractions are a great way to make code easier to reason about. You donāt have to worry about the implementation details and can just focus on the high-level concept. Itās important to keep in mind that good abstractions are amazing but bad abstractions will make your life miserable. Use them wisely.
If itās a bad abstraction, it wonāt represent the high-level concept well. This often means you need to be aware of many of the implementation details to use it. To make it even worse, bad abstractions often have a negative compounding effect on the codebase. Making everything that uses it needlessly more complicated.
Getting rid of bad abstractions in time is crucial, which naturally leads to the next principle.
Refactor ruthlessly
There are two reasons for why refactoring is valuable
- Code can always be improved
- Changing code can uncover bad design
Not refactoring enough can result in a vicious cycle:
- Thereās friction when making changes
- Developers build around the code instead of changing the code
- The code becomes more difficult to understand
- Thereās even more friction when making changes
š§¹ You Should Refactor More Than You Think is an article that focuses on this particular principle.
Manage dependencies
Avoid unnecessary dependencies, but more importantly, make sure dependencies make sense. Circular dependencies will come back to haunt you.
Write stateless code
State is hard to reason about and much more difficult to test. Of course, there will almost always be at least some form of state, but splitting that from stateless code will make it much easier to understand and debug.
Automated Tools over Manual Guidelines
The simplest example of this is formatting. Itās always better to have an automated formatting tool than expect developers to point out formatting issues in Code Reviews.
Folder structure
Keep test files next to code files. All related code files should live as closely together as possible.