Being strong believers in the SOLID principles we discussed in the previous chapter, several prominent figures in the Go community strongly advise software engineers to organize their code into self-contained and reusable packages.
When our code imports an external package, its dependency graph is augmented not only with the imported package but also with its set of transitive dependencies—that is, any other packages (and their dependencies) required by the packages that we import. As our projects grow larger in size, it becomes necessary to efficiently manage the versions of all our dependencies to ensure that changes in upstream transitive dependencies do not cause unexpected side effects (crashes, changes in behavior, and so on) to our own programs.
In this chapter,...