I want to keep this is as abstract as possible. I have a project where a high-level component "C" relies directly on "B". In turn, "B" relies directly on "A" so "C" indirectly relies on "A" too.<p>Therefore, the hierarchy is C->B->A.<p>Currently, all of these components are in active development and are having major changes made. Changing anything in A is requiring adapting of code in B which in turn requires adapting of code in C. Changing B requires modification of A.<p>My question is if anybody has advice on how to avoid this and to some degree mitigate the issue to make development of "B" and "A" easier without breaking upstream components.<p>In my specific situation, the actual components are "C" = an object/model handling class, "B" = an abstract version of that class with common functions for all the models, "A" = a database handler. So I hope you see how changing A or B requires rewrites of C and/or B.
This would suggest to me that you have a Coupling mistake or an Abstraction problem of some sort. I can't quite offer specific fixes based on the specifics here, but abstractly my gut reaction is that it sounds likely that B is too tightly coupled to A and is likely something that either should be part of A or C more directly (possibly merged together; or at the very least versioned together).<p>Certainly I don't often feel like an abstract class is a separate enough concern to be its own module (an abstract class without any available implementation is useless on its own), and that seems a flag that maybe should reconsider your architecture, but without too many specifics I'm not sure I can tell you exactly what is wrong with your abstract class.<p>Hope that helps maybe lead you in the right direction at least.
What exactly is changing? Are these completely separate pieces as in can they be separately deployed services? Or are you talking about a View layer, middle/business layer, db layer in the same app? If they can be separate apps, then create APIs with agreed upon interfaces. Then do not change those interface contracts. Version them if they need to change then the other components can still use the old version while upgrading to the newer version of the interface contract if needed