Coupling and Modularity
Modularity’s perks, we cannot ignore,
But its true essence, we still must explore.
What makes a design coherent and fluent?
It’s all about value—future and current.
“95% of the words are spent extolling the benefits of modularity, and little, if anything, is said about how to achieve it” (Myers 1979). These words were written over 40 years ago, but the observation remains true to this day. The significance of modularity is unquestionable: It is the cornerstone of any well-designed system. Yet, despite the many new patterns, architectural styles, and methodologies that have emerged over the years, attaining modularity is still a challenge for many software projects.
The topic of this chapter is modularity and its relationship to coupling. I’ll start by defining what modules are and what makes a system modular. Next, you will learn about design considerations that are essential for increasing the modularity of a system and avoiding complex interactions. Ultimately, the chapter discusses the role of cross-component interactions in modular systems, which paves the way for using coupling as a design tool in the chapters that follow.
Modularity
Not only is the notion of modularity not unique to software design, but the term “module” predates software design by about 500 years. At its core, modularity refers to systems composed of self-contained units called modules. At the same time, you may recall that in Chapter 1, I defined a system as a set of components. This naturally raises an intriguing question: What distinguishes the components of a traditional system from the modules of a modular system?
A system has a goal: the functionality it has to implement. The components of the system are working together to achieve the goal. For example, a social media app enables people to connect, share, and interact, while an accounting system streamlines financial tasks for businesses. However, these functionalities only address the present requirements. As time goes on, the users’ needs may change, and new requirements may emerge. That’s where modularity comes into play.
Modular design aims to address a wider range of goals than a nonmodular system can. It expands the system’s goal to accommodate requirements that are currently unknown but may be needed in the future. Of course, the future requirements are not expected to be available out of the box on day one, but the design should make it possible to evolve the system with a reasonable effort.
By investing in modularity, we design an adaptable and flexible system. That is, the primary goal of modularity is to allow the system to evolve (Cunningham 1992). A famous quote that is often (mis)attributed to Charles Darwin1 captures this idea perfectly: “It is not the strongest of the species that survives, but the most adaptable.” This principle applies to systems as well. Even the most finely tuned, faultlessly performing system of today will face obsolescence if it cannot flex and grow with tomorrow’s changes. The less flexible a system is, the less stress it can tolerate. The less stress it can tolerate, the more prone it is to breaking under the pressure of evolving requirements. By being prepared to handle changes, a modular system is better positioned for long-term success.
Modularity also serves as a cognitive tool, streamlining the comprehension of a system. Instead of a monolithic, inscrutable black box, a modular system presents as a collective of individual parts, each performing its function yet able to function collaboratively. This separation into modules allows for a clearer understanding of the system’s inner mechanics and how it ultimately delivers the desired output.
But why does this matter? Is it simply a matter of satisfying intellectual curiosity? Not really. A deep understanding of how a system operates is the key to modifying and improving it. This might involve altering existing behavior, such as fixing bugs, or it could involve evolution of the system by introducing new functionalities. The simplicity and transparency of a modular design enable you to tinker, adjust, and innovate more effectively and with more confidence.
With this understanding of the importance of modularity, let’s dig deeper into the concept of a module and its role in making a flexible system.