The package principles, popularized by Robert C. Martin, are a set of guidelines regarding the partitioning of a software product’s codebase into discreet and reusable packages. A package is a unit of code organization one step above classes/modules. Just as Martin’s SOLID principles guide the organization of code into classes/modules, the package principles guide the organization of classes/modules into packages. The two sets of guidelines may be considered complementary and are in some ways analogous, albeit for different units.
In short, the package principles argue for the consideration of two key aspects when packaging code: granularity; and, stability. Granularity is a measure of the degree to which the classes in a given package are related to one another, reused in the same ways, and changed for the same reasons. Ideally, a package should contain only classes that can be reused together because when one package is made a dependency of a project, all of its constituent classes are necessarily also dependencies of that project, regardless of how many are actually used. For its part, stability is a measure of how often a package is changed and for what reason. Ideally, package dependencies should flow down so as to avoid cyclic release issues where a change in one affects all those down the line, and vice versa. Moreover, the measure of a package’s abstraction should be proportionally related to its stability. That is, a highly stable package should also be highly abstract to allow for extension.