Types of Cohesion
Modularity Fundamentals
In a previous article titled What is Modularity? we briefly explained that high cohesion and low coupling indicate a well-designed modular decomposition. Both cohesion and coupling come in several types. Here, we explain the various types of cohesion.
But First, Remind me — What is Cohesion?
As explained in the previous article, a module is said to be highly cohesive if its constituents are strongly related and work towards a common goal.
Similarly, the modules have low coupling if they have minimal and simple interconnections. Both cohesion and coupling are measures of modularity and a “high” of one is often correlated with a “low” of the other as shown in the figure below, so it’s difficult to talk about one without mentioning the other.
In design (i) shown above, order management function is distributed across multiple modules. In design (ii), it is brought together in a single highly cohesive Order Management module. High cohesion makes it easier to understand and maintain the module’s design and source code. For instance, in the particular case of the Order Management (OM) module, high cohesion has the following benefits:
- It’s easier to understand and reason about the module’s functional and technical behaviors.
- It’s easier test the module independently. Apart from unit tests that validate business logic, you can test the functional behaviors by exercising the module’s interfaces (say, API).
- Any changes in order management behaviors is likely to impact only the Order Management module. Also, it is easier to build expertise in the module as all related constituents are together. Introducing enhancements and fixing bugs should become easier, both due to limited impact and expertise.
The Spectrum of Choices of Cohesion
Cohesion comes in various types or degrees. The figure below depicts them on a graded scale comprising the least desirable type to the most desirable one.
The following subsections describe the types.
Coincidental Cohesion
A module exhibits coincidental cohesion if its constituents are arbitrarily grouped together for no particular reason and perform unrelated tasks.
Coincidental cohesion is the worst form of cohesion and is best avoided except in the the simplest of the applications.
Logical Cohesion
A module is logically cohesive if its constituents are grouped together because they perform logically similar tasks.
A couple of examples:
- A
Utilities
module, which groups utilities/helpers for the entire application. - A
Transaction
module, which groups components that perform different kinds of business transactions such as creating and managing users, customers, products, orders, payments, etc.
Logical cohesion should generally be avoided. However, it can be useful sometimes when used in conjunction with higher degrees of cohesion. You could group solution domain constructs like layers, utilities, and so on, in logically cohesive sub-modules under a functionally cohesive parent module, as illustrated in the figure below.
At a source code level, the modules shown in the figure above may be represented as packages/namespaces of the following form:
com.mycompany.ecommerce.ordermanagement.utilities
(Java) /MyCompany.Ecommerce.OrderManagement.Utilities
(C#)com.mycompany.ecommerce.productinfomanagement.utilities
(Java) /MyCompany.Ecommerce.ProductInfoManagement.Utilities
(C#)
Temporal Cohesion
A module exhibits temporal cohesion if its constituents are grouped together only because they are related in time. The constituents of a temporally cohesive module are only weakly related to each other.
An Initializer
or System Startup
module that encapsulates and performs initialization/startup tasks for the entire system, is an example of a temporally cohesive module. It is shown in design (i) in the following figure.
Design (ii) in the above figure shows an improved and more maintainable design, where the module coordinates the startup process, but delegates module startup to respective tasks in other modules.
Procedural Cohesion
A module exhibits procedural cohesion if its constituents are grouped together because they are related by order of execution (although they don’t share data).
A good example is an “Payments File Processor” module that performs the following tasks in sequence:
- Check file permissions.
- Reads the file to extract records. Each record represents a received payment.
- Computes cumulative payments.
- Prepares a payments report.
- Publishes the report.
- Sends email to announce availability of the report.
Procedural cohesion is a moderate form of cohesion.
Communication Cohesion
A module exhibits communication cohesion if its constituents are grouped together because they operate on the same inputs and outputs, such as a file, a record in the database, or a data structure.
For example, consider a hypotheticalBill Items Reader
module that performs a bunch of tasks on the same set of bills:
- Reads recent bills to extracts items.
- Transforms the bills for further processing.
- Generates a periodic report based on the bills.
- Computes and stores cumulative bill stats for a dashboard.
Sequential Cohesion
A module exhibits sequential cohesion if its constituents are grouped together because each constituent’s output is used as input by the next one.
The following figure illustrates a Data Processing module that exhibits sequential cohesion.
The constituents of the Data Processing module in the example above are grouped together because they perform the following tasks in a sequence:
- The File Reader component reads the file, then passes the content to the Format Translator component.
- The Format Translator translates the format and then sends the content to the File Compressor.
- The File Compressor compresses the files and passed the compressed file to the File Uploader.
- The File Uploader then uploads the compressed file to the Cloud Object Storage destination.
Sequential cohesion is a relatively strong form of cohesion. Functional cohesion, which is discussed in the next section, is even better.
Functional Cohesion
A module is functionally cohesive if its constituents are grouped together because they work together towards fulfilling a single, common business function.
In the example shown in the figure below, each module is responsible for a single business function.
Assuming that each constituent work towards the same business function that the module serves, each of the modules shown above is functionally cohesive.
This a strong form of cohesion and among the best.
Conclusion
There are various degrees of cohesion ranging from coincidental cohesion where the constituents are more or less unrelated to each other and perform unrelated tasks, to functional cohesion they are strongly related to each other and work together towards a shared business goal.
In most cases, you should aim for making your modules functionally cohesive. If you can’t - explore using lower forms of cohesion like sequential, communication, procedural, temporal and logical. You could also use them in conjunction — say, functional cohesion for a parent module like com.mycompany.ecommerce.ordermanagement
and logical cohesion for a child module like com.mycompany.ecommerce.ordermanagement.utilities
.