0

I'm studying design principles, and I have a doubt in package coupling principles.

I know that the 'Stable Abstraction Principle' says that a package should be as abstract as stable, and it says that we need to keep concrete packages (which are irresponsible and unstable) at an high level to make changes easier, and abstract packages (which are responsible and stable) at a low level to make dependencies easier.

But why? It shouldn't be that higher level packages are ones from which others will depend, and at an higher abstraction level?

Thanks to all!

2
  • 1
    the point about stability is how often something is likely to change. If you write software which depends on something that changes, then you need to re-test that component every time you update to a new version; then you might find that something doesn't quite work the same way any more so then you need to fix it. "unstable" could be described as "likely to change often" whereas "stable" could be described as "only likely to change very rarely/infrequently", also with changes to stable components ideally being less risky than the kinds of changes in unstable ones too. Nov 16 '21 at 16:25
  • @BenCottrell So we need to write software in a way that we should need to change only higher level packages, and leave lower level packages in a way that we'll never need to change them (as much as possible)?
    – Gius
    Nov 16 '21 at 16:32
3

You are right when it comes to structuring - e.g., organizing the system into layers. What we refer to "high-level" code/layer should be composed of the more stable abstractions/concepts, so that the more volatile pieces of code can, for the most part, be changed in isolation behind those. Otherwise no change would be confined because of backpropagation down dependency chains, while this way, the stability of the high level components enables changes to the more volatile concepts to be worked into the existing system.

However, I'm guessing that what the text is trying to say is that, for unstable code, you should design/find a higher-level, more stable abstraction (e.g. an interface) behind which you can encapsulate it, and make all calls through that. In other words, abstract away unstable aspects of the system, and think of the abstraction itself as the primary thing against which you'll write other code. Make the concept abstract, keep the implementation details concrete, and possibly place them into separate packages (or DLLs, or whatever).

Stable concepts on the other hand, if they don't encapsulate variation behind them, can safely be concrete classes. So stable concepts can be represented by a combination of concrete classes and data structures and abstract types, leaning generally towards abstractness, while volatile concepts are better off behind a facade or a polymorphic interface (these forming the "API" of the various encapsulated components, with the logic in the calling code expressed in terms of that "API"). Note that, structurally, you'd place such facades and interfaces in a higher-level layer (higher level w/ respect to where the concrete, volatile implementations are placed), and you'd use dependency inversion in order to achieve that. Of course, this can be done at multiple organizational levels (subsystems, packages, classes, ...).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.