2 Code and project organization


This chapter covers

  • Organizing our code idiomatically
  • Dealing efficiently with abstractions: interfaces and generics
  • Best practices regarding how to structure a project

Organizing a Go codebase in a clean, idiomatic, and maintainable manner isn’t an easy task. It requires experience and even mistakes to understand all the best practices related to code and project organization. What are the traps to avoid (for example, variable shadowing and nested code abuse)? How do we structure packages? When and where do we use interfaces or generics, init functions, and utility packages? In this chapter, we examine common organizational mistakes.

2.1 #1: Unintended variable shadowing

The scope of a variable refers to the places a variable can be referenced: in other words, the part of an application where a name binding is valid. In Go, a variable name declared in a block can be redeclared in an inner block. This principle, called variable shadowing, is prone to common mistakes.

The following example shows an unintended side effect because of a shadowed variable. It creates an HTTP client in two different ways, depending on the value of a tracing Boolean:

2.2 #2: Unnecessary nested code

2.3 #3: Misusing init functions

2.3.1 Concepts

2.3.2 When to use init functions

2.4 #4: Overusing getters and setters

2.5 #5: Interface pollution

2.5.1 Concepts

2.5.2 When to use interfaces

2.5.3 Interface pollution

2.6 #6: Interface on the producer side

2.7 #7: Returning interfaces

2.8 #8: any says nothing

2.9 #9: Being confused about when to use generics