On the criteria to be used in decomposing systems into modules[PDF] is a classical 1971 paper by David L Parnas which discusses
modularization as a mechanism for improving the flexibility and comprehensibility of a system while allowing the shortening of its development time.
The key point of the paper is that:
the effectiveness of modularization depends on the criteria used in dividing the system into modules.
More specifically, and quoting from the conclusion in part, which is my main take-away from the paper:
It is almost always wrong to begin decomposing a system based on a flowchart. instead one should begin with a list of difficult design decisions or design decisions which are likely to change.
Modularization and its benefits
"But wait", I hear you say, or at least I can imagine you say, "before you go any further quoting copiously from the paper, what is modularization and what benefits do I stand to gain from it?" I am glad you asked. Allow me to quote from Wikipedia:
Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality.
From the above, we can deduce that modularization does not necessarily only refer to breaking a program into functions and classes. It could as well refer to breaking a monolith into micro-services, for example.
In fact, according to the author:
Modularizations are intended to describe the design decisions which must be made before the work on independent modules can begin. Although quite different decisions are made in each alternative, in all cases the intention is to describe all "system level" decisions (i.e., decisions which affect more than one module)
The author highlights three classes of benefits that are expected from modularization.
- managerial - shortened development time because separate groups would work on each module with little need for communication.
- flexibility - ability to make quite drastic changes or improvements in one module without changing others.
- comprehensibility - the system could be studied a module at a time with the result that the whole system could be better designed because it was better understood.
Other benefits could include:
- easier to test and debug.
- modules can be easily reused for other applications.
Going back to the central theme of the paper, and I think it is worth repeating here, these benefits might not be achieved if the wrong criteria is used in decomposing a system.
Types of modularization/decompostion
Hence the author then presents two methods of decomposition. 1.Procedural decomposition, in which the criteria is to make each major step a module. It's usually a result of making a flowchart diagram. He refers to this approach as the conventional approach because this is the approach most programmers would take:
This is a modularization in the sense meant by all proponents of modular programming. The system is divided into a number of relatively independent modules with well defined interfaces; each one is small enough and simple enough to be thoroughly understood and well programmed.
The author argues that for larger systems, and in fact any system where requirements change often, this approach leads to tight coupling between modules and ultimately defeats the benefits of modularization.
- Unconventional decomposition which 'information hiding' as a criteria.
In this approach:
Every module is characterized by its knowledge of a design decision which it hides from all others. Its interface or definition was chosen to reveal as little as possible about its inner workings.
The author notes that the unconventional method, when properly followed, introduces a hierarchical structure among the modules. That is, some modules are on a "lower level" than others. This creates a relation in which say higher level components "depend upon" lower level ones. This brings added advantage of reusability, that is, the lower level components can be used in other applications.
Show me an example
The author compares the two methods of decomposition using two sample problems:
To be honest I struggled a bit to follow the example systems. But I found the scheduling calendar example here more relatable.
I particularly like the strategy proposed by Thomas Vilhena for effective system modularization, which are as follows:
- Enlist all operations the system is required to implement
- Anticipate possible improvement/change requests for these operations
- Identify design decisions likely to change, prioritizing them if necessary
- Extract specialized modules that encapsulate these design decisions
- Establish and maintain a clear hierarchical structure within the system