Big Blue Series — 19 — Healthy Modularity Enables the “ilities”
We all hear about it. We need scalability, agility or flexibility, elasticity, maintainability, and I could go on and on. What I am learning about this is that if you focus on any one of those too much you ignore the others and become out of balance. There are many pressures by the real world already, but to make software under powered by the structures we choose can mean a loss of millions of dollars in revenue, especially in markets where speed to market is held up by the development process. There is no silver bullet in software, except maybe the poorly architected platform that kills a business.
We can do this differently. In the first 18 articles the essence of those articles was to learn from Blue (Evans, 2004) how to model the business at the highest-level identifying Domains to Bounded Contexts. Then we learned about the building blocks of a model: Entities, Value Objects, Services, and Events. Once those are clearly understood, we can then group those into living organisms called Aggregates. And then, of course, if Aggregates are complex then we make them realized in software using Factories and save and retrieve them in Repositories.
Here is the rub, we could have 20 to 100 aggregates in a Bounded Context. That is a little too much to package up in one software package. We need Modules. The concept of a Module was saved until now because this is more architectural, but it is still a model concept. Modules are a mid-level structure that allow for nice groupings of Aggregates and Services that in a nutshell segregates those Aggregates together so that we have a conceptual whole, without other concepts bleeding in.
And don’t worry, we all group things less efficiently at first because we don’t know enough to know what is efficient until Domain Intel is revealed over time.
Too Many Items
If you have one Module and all your code is in it, that is a Monolith not a Module.
If you have more than one Module and some of your Modules have too many items, then you have smaller types of monoliths. You know this is happening when there are too many unrelated parts being deployed with a change in one little area, just as in the classic Monolith structure. It is time to break things down. This is not easy and requires the nerves to do as @Kent Beck taught us in Amsterdam back in 2020 at DDDEU. “Make change easy, then make the easy change.”
But it would be better if your teams learned to morph modules at the same time, they are changing Aggregates or Bounded Contexts when the Module is starting to hold more than it should in the first place.
Too Few Items
This is less common, but the overzealous will start to make more modules than are needed. This is also not as maintainable when Aggregates that should be together are not. You know this is happening when you have Module dependencies that require deployment coordination for these modules frequently.
Here is an Idea
So, I added an image of a fern leaf as the lead image for a reason. Plants don’t have a general problem with the process of grouping cells into leaves, leaves onto branches and branches onto other branches and then connect all of that onto trunks if it is a tree.
There are several things we can learn from this plant model.
Rather than help you imagine the quality of a well-orchestrated “leaf-branch-trunk-root” system which I think you can easily imagine, let’s look at something more interesting. Deformities.
Malformed leaves are noticeable. They have weird shapes and maybe are even looking more dead than their friends on the branch.
After you have been learning your Domain for a while, and if you have been doing software for a bit, deformities make one feel a little, well, uneasy is a good way to say it. It is, in a sense, the Force (Star Wars) telling you there is a disturbance in this structure. I would not recommend you ignore this. You might add a TODO to your code, or you might call everyone over to remodel this Module but do something. The more you own this, the better the software gets over time at the “ilities”
Static and Dynamic Deformities
There are many things to say about where the deformities may come from, but there is a great book entitled “Software Architecture: The Hard Parts” (Ford et al., 2021) If you are really interested in tackling complexity in the modularity issues of your software, then I do recommend this read — I won’t say it better than they did. They dive into what it means to have too many connections in the way the code is written (static) and too many communications between modules (dynamic).
Wisdom
Lastly, it pays not to over or under engineer the Modular structure of your software. Keep your eye on this. The inside of a Module is generally much easier to change than the framework of all the modules themselves. This is why Monoliths die hard. Microliths have this same issue. This is why this is one of the hardest parts of software. You need to be able to anticipate and roll with change at a level that historically does not change easily.
Questions to Ask
- Would I want this code to deploy with all this other code? Are they in the exact same family?
- Can this Module split and legitimately each new Module deploy independently?
- Am I always deploying these Modules together? (Why not make them one!)
The path to the next topic is filled with many options…
Until then…
I hope I see you in the next installment of — the Big Blue Series.
References
Evans, E. (2004). Domain-Driven Design: Tackling Complexity in the heart of software. Addison-Wesley Professional
Ford, N., Richards, M., Sadalage, P., & Dehghani, Z. (2021). Software architecture: The hard parts: Modern trade-off analyses for distributed architectures (1st ed.). O’Reilly Media.