In my last post, I introduced Uncle Bob Martin’s principles for dividing classes into packages.
Part 1 talks about three principles related to package cohesion. A discussion on Ruby Rogues Parley helped me realize that these principles also apply to the services in a Service-Oriented Architecture. A couple of years ago, Uncle Bob wrote Service Oriented Agony where he talks about how the Common Closure Principle can apply in this domain.
In this post, let’s look at the three principles related to package coupling.
The remaining three principles are about package coupling. That is, how do our packages relate to each other?
The Acyclic-Dependencies Principle (ADP)
Allow no cycles in the package-dependency graph.
When two or more packages are involved in a dependency cycle, it becomes very difficult to stabilize the application. Changes to any package in the cycle result in changes being required in every other package in the cycle.
It also becomes harder to isolate packages for testing purposes or to extract packages for re-use in a different context, because you end up transitively depending on every other package in the cycle.
A naive automated build system can be completely defeated by a cycle in the package graph, getting stuck in an infinite loop of constant rebuilding.
The Stable-Dependencies Principle (SDP)
Depend in the direction of stability.
Package dependencies should be structured such that the parts of the system that have to change frequently depend on the parts of the system that don’t change very much.
Things that don’t change much, such as high-level design and architecture decisions, can have many dependents. But things that change a lot should have very few dependents.
Most projects have a number of utilities that get grouped together into a small set of packages. These utilities are then used by almost every other package in the system.
Each utility is likely relatively stable, but we constantly add new utilities to the package over time, making the package itself less stable. According to this principle (and the next), the utility package idea is not ideal. I don’t yet have a good alternative solution to propose, however.
The Stable-Abstractions Principle (SAP)
A package should be as abstract as it is stable.
Stable packages should be more abstract, containing classes and modules that can be extended, rather than classes and modules that have to be directly changed a lot.
Again, consider the utility packages that many projects have. These utilities are about as concrete as they come, and yet every other package in the system depends on them.
* Agile Software Development: Principles, Patterns, and Practices: This is Uncle Bob’s book that introduces all of these principles. All of the quoted principle summaries above are taken from this book.
* Principles of OOD: Blog post by Uncle Bob briefly describing the principles.
* Object Mentor Articles: Numerous articles by Uncle Bob and others from Object Mentor on many topics. I learned a lot by reading these articles when they were written, and they have significantly shaped how I think about software today.