All posts
Jun 1, 2023 in Architecture4 min
Real-world Architecture: Stable Dependencies Principle
Posted by
Ragunath Jawahar
Ragunath Jawahar
@ragunathjawahar

Most projects have humble beginnings. They usually start with a single module, and as they deliver more value to their users, they grow and become more complex. If the project is successful, the development teams that maintain these projects may break the single module into several smaller modules or create new ones to make the project maintainable, reusable, and in some cases—independently deployable.

Handling several modules may seem straightforward if you have prior experience with a multi-module project. However, to make the best of modular projects, we should pay close attention to how we define and manage the dependencies between these modules. This article aims to help you understand the underlying principles and metrics that govern these ideas.

1. Stability—the ability to change

Before jumping to conclusions about stability, whether good or bad, etc., We must understand that we need stable, unstable modules and everything between these two extremities in a software project. When discussing stability in the context of dependencies, we define it in terms of,

  1. How easy or hard is it for the module to change?
  2. How much impact can a module have on other modules during such changes?

We can count the number of outgoing and incoming dependencies of a module to answer both of these questions. It is important to remember that stability is a spectrum with opposing extremities and a wide range between these extremities. Let's take a look at them one by one.

1.1 Maximally stable

A maximally stable module
A maximally stable module

In this example, the module we are interested in is A. You can see it has 3 dependents but does not depend on any other modules. So, in this case,

  1. It can be hard to change A, because other modules depend on it.
  2. Changing A could have an impact on X, Y, and Z.

We call A maximally stable because it has incoming dependencies but no outgoing ones. The module is also colored in orange to make it easier for us to identify it in larger module diagrams, and this is a convention we will follow.

1.2 Maximally unstable

The other end of the spectrum is the maximally unstable module; a more appropriate term would be 'flexible'. Bear in mind the word unstable does not mean undesirable or harmful. It only refers to the module's attributes regarding changeability and the impact of such change.

A maximally unstable module
A maximally unstable module

In the diagram above, you can see that B depends on 3 other modules. Any change in one of these modules can affect B. Therefore, we can infer B to be unstable. Besides, in terms of changeability and impact,

  1. B has no dependencies; therefore, changing it can be easy.
  2. Changing B may not affect other modules.

Module B is maximally unstable because it has several outgoing dependencies but no incoming dependencies. We have also colored this in blue to make it easier to identify in larger diagrams as a convention.

2. Instability

Now that we have looked into the extremities of stability, we must look into the spectrum in-between. You may have already noticed the number of incoming and outgoing dependencies defines the stability of a module. We can use the instability metric (I) to express the module's instability as a number. The following is the expression for computing instability (I).

I = outgoing / (incoming + outgoing)

Where,

  • 'I' is the instability metric between 0 and 1.
  • 'outgoing' represents the number of dependencies.
  • 'incoming' means the number of dependents.

Therefore, for maximally stable modules, I=0, and for maximally unstable modules, I=1. For other modules, 0 < I < 1.

For example,

A dependency chain with maximally stable, unstable, and in-between modules
A dependency chain with maximally stable, unstable, and in-between modules

Let's take a closer look at module B in the diagram. It has 1 incoming dependency and 1 outgoing dependency. If we compute instability,

I = 1 / (1 + 1) = 0.50

The diagram also introduces a new notation below the module name. For example, we have (1, 1, I=0.50) under B. The first value denotes the number of outgoing dependencies, the second the number of incoming dependencies, and the final value is the instability metric. We'll use this as another convention in all our dependency diagrams. We also colored the module orange but with opacity based on the instability metric.

3. Stable Dependencies Principle

Now that we've set the stage, it's time to introduce the stable dependencies principle. It simply says,

Depend on the direction of stability.

The statement means less stable modules should depend on more stable ones. In other words, the I metrics should keep decreasing in the direction of dependency.

A dependency chain adhering to the stable dependencies principle
A dependency chain adhering to the stable dependencies principle

In the diagram above, A -> B -> C and their corresponding I metrics are 1.0 > 0.50 > 0.0. Since the metric decreases in the direction of the dependency, we can say the dependency chain conforms to the principle.

Conclusion

The article introduced key concepts, terminologies, and conventions that we could use to understand and analyze large multi-module projects. As a recap, you should be familiar with the following:

  • Maximally stable modules
  • Maximally unstable modules
  • Instability metric (I)
  • Stable Dependencies Principle
  • Colors and conventions for modules in the dependency diagram

In the upcoming articles, we will use these ideas to discuss how they apply to real-world projects and what inferences we could make from module dependency diagrams.

If you gained value from this blog post and would like to get notified with the following articles, consider subscribing. Until next time!

Overall, how helpful was this article?
😭🙁🙂😍

Stay ahead of the curve! 🚀

Subscribe now and never miss our cutting-edge, innovative content.
Address
Legacy Code Headquarters (OPC) Private Limited,
L-148, 5th Main Road,
Sector 6, HSR Layout,
Bengaluru, Karnataka-560102,
India.
© 2023–2024 Legacy Code HQ. All rights reserved.