What is Modularity, Cohesion, Coupling and Connascence?
Introduction
Hello there! In this article, we will discuss what modularity is and explore three key concepts related to it:
- Cohesion
- Coupling
- Connascence
Module and Modularity
In short, A module is a self-contained unit that performs a specific task or function within our program.
We use modularity to describe a logical grouping of related code, which could be a group of classes or a group of functions. Modularity is an organizing principle. The goal of modularity is to break down a complex system into smaller, manageable parts, which can be developed, tested, and maintained independently.
Cohesion
Cohesion is a measure of the relationship between parts within a module. A cohesive module is one in which all the parts are closely related and should be packaged together. Breaking them into smaller pieces would require coupling the parts through calls between the new modules, and of course, it will decrease readability.
Range of cohesion measures (listed from best to worst):
- Functional: Every part of the module is related to the others through function calls.
- Sequential: Two modules interact, where one module outputs data that serves as the input for the other module.
- Communicational: Two modules form a communication chain, with each module operating on information and contributing to the overall output.
- Procedural: Two modules must execute code in a particular order.
- Temporal: Modules are related based on timing dependencies, such as initializing many things at system or program startup.
- Logical: The data within modules is related logically but not functionally. For example
Math
in javascript. It contains functions for performing mathematical operations, Each function within the module is logically related to the overall purpose of performing mathematical calculations. - Coincidental: Elements in a module are not related other than being in the same source file; this represents the most negative form of cohesion.
Coupling
Coupling refers to the level of interdependence between modules in a system. It measures how much one module relies on or interacts with another module.
afferent and efferent coupling
- Afferent coupling measures the number of incoming connections to a code artifact, such as a class or function. It quantifies the dependencies and interactions of the given artifact with other artifacts.
- Efferent coupling measures the number of outgoing connections from a code artifact to other artifacts.
Abstractness
Abstractness is the ratio of abstract artifacts, such as abstract classes and interfaces, to concrete artifacts in a codebase. It measures the balance between abstract concepts and their implementations. Having an excessive number of abstractions can make it challenging for developers to comprehend how different components interact. Conversely, lacking abstractions leads to a monolithic codebase that is difficult to understand and maintain. Striking the right balance between abstractness and implementation is crucial for code readability and maintainability.
Instability
Instability is defined as the ratio of efferent coupling to the sum of efferent and afferent coupling. A codebase with high coupling is more prone to breaking when changes are made, leading to increased instability.
Excessive abstraction in code can make it challenging to use, while insufficient abstraction with excessive implementation can lead to code that is fragile and difficult to maintain. Therefore, it is crucial to strike the right balance and be mindful of employing appropriate levels of abstraction in our code.
Connascence
Two components are connascent if a change in one would require the other to be modified in order to maintain the overall correctness of the system.
— Meilir Page-Jones
There are two types of connascence: static and dynamic.
Static Connascence
Static connascence refers to coupling at the source code level, irrespective of whether it is afferent or efferent coupling. It can be identified during compile-time.
Types of static connascence (listed from easy to hard):
- Connascence of Name (CoN): Multiple components must agree on the name of an entity.
- Connascence of Type (CoT): Multiple components must agree on the type of an entity.
- Connascence of Meaning (CoM) or Connascence of Convention (CoC): Multiple components must agree on the meaning of particular values. For example
true = 1
andfalse = 0
; Imagine the consequences of flipping these values! - Connascence of Position (CoP): Multiple components must agree on the order of values.
- Connascence of Algorithm (CoA): Multiple components must agree on a particular algorithm. For example Consider network security algorithms and protocols.
Dynamic Connascence
Dynamic connascence is a type of connascence that occurs due to runtime dependencies within a software system. It can only be identified during program execution.
Types of dynamic connascence (listed from easy to hard):
- Connascence of Execution (CoE): The order of execution of multiple components is important.
- Connascence of Timing (CoT): The timing of executing multiple components is crucial. For instance, a race condition can occur when two threads execute simultaneously.
- Connascence of Values (CoV): Connascence occurs when multiple values are interrelated and must change together. For instance, consider a distributed system with separate databases, where you need to update a single value across all the databases.
- Connascence of Identity (CoI): This situation arises when multiple components need to reference the same entity. For instance, consider a scenario where two independent components need to update a distributed queue.
Connascence properties
- Strength: The strength of connascence is determined by how easily a developer can refactor the coupling of that type.
- Locality: Connascence locality measures the proximity of modules within a code base. Code that is in close proximity (within the same module), generally exhibits higher forms of connascence compared to code that is more separated (in separate modules or code bases).
- Degree: The degree of connascence relates to its impact, whether it affects a few classes or many.
And we’re done! In this discussion, we covered the concept of modularity and explored some fundamental ideas of cohesion, coupling, and connascence.
Hope you enjoy!