Modularization is obviously important in software projects, but I want to know people's opinions on how important and for what reasons it is important. I've obviously got my own ideas since I'm asking this, but think of it like a "common brainstorm" of the reasons one should modularize one's software projects...
My main reasons for putting code into different modules:
- Separation of concerns: I feel that it is easier to limit the knowledge about the internals of classes on different levels or with different tasks if they are organized into separate modules. It simply feels more "dirty" to rely on internals if they are well hidden.
- Easier to maintain smaller components: I usually find the development environment to be more responsive if I am working on a project with fewer code files, than if the project contains hundreds and hundreds of files.
- Prevention of namespace clashes: When properly modularised, e.g. using namespaces in Java, you can have the same function name for the same functionality without having to worry that the printout() function in the Foo component will clash with the printout() function in the Bar component.
- Separation of security concerns: It is easier to minimise the potential damage when one component steps on the toes of another component. Depending on the technology being used you can limit where each module can play in memory.
I think one of the main aspects is reuse. When you build things modularly, there's hardly things like: "Oh, I've already done this before, but to use it, I'll also have to get this and this functionality, which has absolutely nothing to do with my application".
Also, it is easier to understand. I can't keep tons of things in my mind at the same time. When the code is modular, there's easier to establish an "area" of things that makes sense in themselves. And once this area tends to be small, I can understand it as whole rather than pieces of it.
Finally, when things are smaller, it is easier to test and maintain. Also, your tests indicate faster where the error is, once they will test only a small part of the application.
We humans are limited when it comes to grasping complex problems all at once. However, we are gifted in the ability to decompose a complex problem into a (possibly very large) number of individual problems that are not too complex in order to tackle the big problem.
This is fundamentally what drives answers like "reuse", "separation of concerns", "easier maintenance".
All of these reasons are true whether it is one person breaking down a complex problem to tackle piece-by-piece, or if it is a team of people breaking it down to distribute the complexity.
Modularization and decoupling are important for many reasons, some are:
- Reuse: It is much easier to reuse software modules that are dedicated to specific purposes
- Managing Complexity: Working on decoupled modules (writing code, debugging, maintaining etc) keeps your focus on a certain domain problem without being distracted by other aspects of the application or the software system.
It can also be viewed as a basic activity of Application Architecture which:
- takes some business and functional specification
- and group the major functions into applications while identifying non-functional modules and pure technical transversal module
That is why a "financial portfolio computation" will actually be divided into:
- a computation module
- a dispatcher module (because a portfolio is too big to be computed on one server)
- a launcher module (to pilot all the computations)
- a GUI (to see what is actually going on)
Plus several transversal ones:
- KPI logging
- Exception management
To treat that kind of functional requirement as one big monolithic module would force the development to implement all the sub-routines in sequence as a all.
Whereas with a clear application architecture, you can begin to work on the more general and transversal modules while still refining the other more business-oriented modules.
It also forces you to define more interfaces, and to analyze the inter-communications issues your different modules will have to solve (direct n-to-n typology? Bus?, ...)