Youve almost surely had to deal with complexity in your software projects. The complexity level of a software application is usually low when development begins, but after a while the complexity begins to increase due to the changes performed on the platform. Complexity keeps increasing constantly as new features are added and the existing functionality is customized. The more changes and customizations are performed, the more complex the system becomesit may get so complex that it becomes difficult for a new developer to ramp up the project and be able to understand all its inner workings. And if the documentation of the system software isnt good enough, then understanding the system becomes even harder. A high level of complexity requires more energy, resources, and time to be spent in order to understand the inner structure of the application.
What is it that causes software systems to become so difficult to maintain? The answer is related to the fact that there are a lot of existing dependencies throughout the code. That happens when a piece of code depends on many other pieces of code, and it can generate a lot of issues. Enhancing such a system becomes painful because making a change on one place may affect many other parts of the application. By modifying an application in many different areas, the risk of introducing new errors grows. Besides that, reaching a satisfactory level of reuse becomes very difficult. The software has so many dependencies that simply reusing a component can become costly in terms of time and it could also further increase complexity. This also hinders the desire to enhance the system. By having a system with many dependencies, adding new functionality becomes a nightmare. Furthermore, the testing process also becomes more difficult because testing separate components is almost impossible to achieve. For you as a developer, understanding every part of the system is hard due to its complexity. As new features are added on a regular basis, and the software system evolves, keeping up to date with the changes can be challenging. In order to mitigate and reduce the negative effects of rising complexity, maintaining the system is mandatory, although maintaining itself becomes demanding in terms of time, effort, and cost.
What do we need in order to get rid of these problems? The answer is modularity.
General Aspects of Modularity
Modularity specifies the interrelation and intercommunication between the parts that comprise a software system. Modular programming defines a concept called the module. Modules are software components that contain data and functions. Integrated with other modules, together they form a unitary software system. Modular programming provides a technique to decompose an entire system into independent software modules. Modularity plays a crucial role in modern software architecture . It divides a big software system into separate entities and helps reduce the complexity of software applications while simultaneously decreasing the development effort.
The goal of modularity is to define new entities that are easy to understand and use. Modular programming is a style of developing software applications by splitting the functionality into different modules software units that contain business logic and have the role of implementing a specific piece of functionality. Modularity enables a clear separation of concerns and assures specialization. It also hides the modules implementation details. Modularity is an important part of agile software development because it allows us to change or refactor modules without breaking other modules.
Two of the most important aspects of modularity are maintainability and reusability, both of which bring great benefits.
Maintainability
Maintainability refers to the degree to which a software system is upgraded or modified after delivery. A big, monolithic software application is hard to maintain, especially if it has many dependencies inside the code.
The architecture of the system and the design patterns used help us create maintainable code. Maintainability is often ensured by simplicity. For instance, one of the simplest ways to improve maintainability is to provide a reference only to the interface that is implemented by the class as a substitute of the class itself. Low maintainability is a consequence of technical debt. Duplicating code may sometimes decrease the level of maintainability. For example, if one piece of code is altered, then other pieces of code that are similar to it also require the same sort of modifications. Because the code is in are many locations, its easy to omit some of the code segments that have to be modified, and this introduces new software issues into the system. The level of maintainability is associated with the quality of the software: the higher the degree of maintainability, the higher the quality of software. Maintainability is enhanced as a result of splitting a monolithic application into a set of modules that present well-defined boundaries between them. In a modular software application, changing a module is easier when it has fewer incoming and outgoing dependencies.
Reusability
Object-oriented programming can be used to obtain reusability, especially via inheritance. In order to reuse the functionality encapsulated in an object, a second object must inherit the first object.
How do modules relate to reusability? It should be possible to reuse a module elsewhere in the same application or in other application. Reusability is the degree to which we can reuse or replace a module. Reusability avoids duplicating code and reduces the number of lines of code, which has a positive impact on the number of software defects. It not only improves software quality, it also helps in developing software faster and makes performing updates on it easier. By applying reusability, the functionality is replicated in a coherent form throughout the entire software system.
Reusability makes the developers job easy because it increases their productivity when developing software components. Modules can be reused because they implement a well-defined interface that makes communication with other modules possible. The interface, which is specified as a contract, allows modules to be exchanged. The module interface is expressed in a standard way so that it may be understood and recognized by other modules. In order to achieve a high degree of software reusability, a module should perform a well-defined function. A design once, deploy many times software architecture is realized by taking advantage of source code reusability. As a property of good software design, reusability is increased by reducing the dependencies between the modules.
Reusability plays an important role in the migration of applications and libraries. Migration becomes simpler when you can reuse software components or modules. Reusability is not easy to achieve because it is challenging to design software that must be successfully used to fit somewhere else.
Module Definition
A software module is an independent and deployable software component of a larger system that interacts with other modules and hides its inner implementation. It has an interface that allows inter-modular communication. The interface defines which components it provides for external use and which components it requires for internal use. A module determines a boundary by specifying which part of the source code is inside the module. It also provides flexibility and increases the reusability of the software system.