- The dependencies between packages should be in the direction of the stability of the packages. A package should only depend upon packages that are more stable than it is. (http://www.objectmentor.com/resources/articles/stability.pdf)
- Richard Riehle, ROAD, ???, (I can't remember the issue at this moment)
- Robert C. Martin, Object Oriented Design Quality Metrics: An Analysis of dependencies, ROAD, Vol. 2, No. 3, Sep-Oct, 1995.
One of the PrinciplesOfObjectOrientedDesign
In architecture (the kind with buildings), a LoadBearingWall
The definition of "stable"
"Stable" roughly means "hard to change", whereas "instable" means "easy to change".
With those definitions, you don't want to maximize stability of all packages. You need instable packages, or your software cannot change easily. If you're doing your job well, the hard-to-change packages will be the ones you never need to change, and the easy-to-change packages will be the ones you have to change frequently. The principle is that no package should be dependent on packages that are more likely to change than it is.
Is there any reason why one package would be inherently less likely to change than another? Wouldn't it be reasonable to expect that lower level packages (which would have more users) to need more changes than higher level packages (which would tend to have fewer users)?
It may be reasonable to expect that, but it is not desirable. High-level packages should not
be dependent on low-level packages; see the DependencyInversionPrinciple
and the StableAbstractionsPrinciple
for more on that point. The whole point of the StableDependenciesPrinciple
is that you want to avoid a situation where you have to make frequent changes to packages with lots of users.
In practically any system, there is an unequal distribution of changes to various packages. In fact, if all packages have fairly equal distributions of change, that's probably a sign of poor organization. The reason is that many design decisions are based upon a desire to support likely changes while simultaneously providing stability. Of course, trying to guess what kinds of changes are likely may not be possible, so if you don't know what types of changes are likely, it is best to wait and see what happens as the system evolves.
This allows us to manage the stability of packages. If we don't want to have to change or recompile a package very often then we must make sure that it doesn't depend on other packages that do change often. Conversely if we want to be able to change a package then we must ensure that other packages that we don't want to have to change don't rely on it.
This advice contradicts the RobertCecilMartin
definition of stability. Because he likes definitions that don't lead to arguments, he defines "stable" as "more incoming dependencies than unstable". (is there a Wiki Link to this ideal?) This can't lead to an argument over "which is more stable?" because you just count each thing's clients and see.
The definition on this page can't apply. It would lead to everyone bunching up on the early leaders.
It is natural for people to make changes to packages that are easy to change, and to avoid changes to packages that are hard to change. In doing so, they make the easy-to-change packages easier to change and the hard-to-change packages harder to change. The principle provides a guideline for determining if things are getting worse or getting better as these natural tendencies take effect. If things are getting worse, then some refactoring may be in order.
says concretes should depend on abstractions. So a better principle than this page's would say "the more things depend on me, the thinner and more abstract I should be".
That's the StableAbstractionsPrinciple, which is described in the same article. Combine that with the StableDependenciesPrinciple, and we get the DependencyInversionPrinciple at a package level (according to Martin).