Main Concepts in Software Architecture
Module vs Subsystem vs Component
I have been always wondering what is the difference between Module, Subsystem, and Component? As simple as it may seem, this is one of the most difficult questions to answer. Each concept from the above has no single unified definition among the software architecture communities. Each community defines and uses these concepts differently, which makes the communications about an architecture difficult to comprehend.
As the software architecture field has been evolving rapidly over time (See The History of Software Architecture story), new terms have been constantly emerging and existing terms' definitions have been continuously changing. As a result, the whole industry struggled to precisely provide universal definitions for many concepts in the IT community and the above concepts are not different.
Personally, I have read tens of books to get a clear answer about the three concepts, and eventually, I reached the most widely accepted definitions among all the communities which I will explain here in this story with an emphasis on how these concepts are complementing each other.
A Module is a logical group of related code, which could be a group of classes in an object-oriented language or a group of functions in a structured or functional language. Most languages provide mechanisms for modularity, for example: in java, it's called a package and in .NET and XML, it's called a namespace, etc.
Accordingly, Modularity is the process of logically grouping a set of related codes.
Its important to note here that a module is a logical grouping mechanism and does not require physical separation (the only exception for this is java, which separates packages into folders and directories as a mechanism to ensure the uniqueness of the classes' names, but from an architectural point of view it's still considered logical grouping not physical).
For example, in the following diagram, we are showing a set of modules where each module embeds a set of classes:
In the above diagram, and although the classes are grouped into multiple modules, they are not physically separated as per the below screenshot (Note: java is still an exception here):
Programming languages usually provide a mechanism to indicate the module name inside the class file itself, usually at the header of the class file itself:
Modules are usually used for maintainability purposes where each module is supposed to be highly cohesive for its internal objects, yet it should be loosely coupled with the other modules. With well-designed modules, the changes on one module don't require changes on the other modules.
A Subsystem is a logical grouping of one or more modules that serves a larger purpose than it is possible for any individual module:
The Subsystem can appear as:
- Logical layer (e.g., presentation layer, application layer, etc.). So the layer is a logical grouping for a specific role within the application
- or as a Logical wrapper for a bounded context as per the Domain-Driven Design (e.g., Contracts, Invoicing, Payments subsystems that shape a larger system for Procurement).
Note here also that the subsystem is still a logical grouping and doesn’t require physical separation. Similar to module but at a larger scale.
Subsystems, similar to modules, are used for enhancing the solution maintainability, and it is also used for manageability. With subsystems, the teams are organized around the subsystems according to their expertise and skillsets. For example, web developers are assigned to the presentation layer, payment expert developers are assigned to payment bounded context, and so on.
A Component is the physical packaging for the modules and subsystems encapsulated behind an interface.
Components are independently deployable by residing inside an execution environment (such as web servers, application servers, containers, etc.)
The Components can appear in:
- Physical libraries (such as jars in Java, DLL in .NET, and gem in Ruby)
- Physically separated subsystem such as a layer that is physically separated, packaged, and deployed into a Tier. or bounded context that is physically separated, packaged, and deployed into a microservice.
As per the above example, we have two physical components deployed on App Server:
- MyWeb.war is a Tier packaging physically the Web Layer
- MyEJB.jar is another Tier packaging physically the Business Layer
As a diagram worth thousands of words, In the following conceptual diagram, I am summarizing the different concepts described in this post and the relationships between them:
Please don't forget to like the post and subscribe to receive notifications for my new stories
About the author
I have 20 years of experience in Software development and Software Architecture. In this page, I will share with you topics based on my expertise related to software development and architecture