Partial enforcement of Law of Demeter.
I refer to Demeter in my Component Model definition, I know its important but the right balance seems to elude me.
Interfaces to decouple dependencies.
Rather than have class A depend on class B. Have class A depend on interface I have B implement I. Thus decoupling A and B by introducing an intermediary I. I think this was discussed earlier in the context of the "Does Static Typing Break Encapsulation". One claim of the Dynamic Typing crowd is that their systems have lower coupling. This is true, however the coupling is now implicit and therefore much more difficult to discover. The better mechanism is to couple objects using interfaces rather than class types. Interesting enough, interfaces aren't present in dynamic typed languages.
Componentize Jars.
Split the system into multiple Jars and explicitly state the dependencies between the Jars.
Remove package dependency cycles.
Reuse only when you absolutely need to.
This has got to be controversial. If you only use a little bit of a jars functionality, why not just copy the snippet into your code?
Dependency inversion.
Interesting, there's an paper on this as applied to AOP: "Aspect-Oriented Dependency Inversion" by Martin Nordberg. I think he did some earlier research on classification of design patterns.
Use some good tools.
Use tools to aid analysis and refactoring of dependencies.
Always fight against Entropy.
This is really interesting stuff we have here, this reminds me of a book that I need to revisit. "Large Scale C++ Software Design" by John Lakos. Lots of insights like "Levelization", "Incremental Insulation" and "Total Insulation".