I once read a column where they compared 3 types of models: the spaghetti model, the Lasagna model and the Ravioli model.
In the Spaghetti model , all the code is interconnected, there is no clear structure. This is terrible, and we can probably all agree to it.
In the Lasagna model, the code is divided into different levels, and only a level of a higher level can refer to a level of a lower level, and not vice versa.
In the Ravioli model, code is grouped into smaller modules. Each module provides only what needs to be disclosed, but each module can access all other modules.
About 10 years ago it seemed to me that the Ravioli model is better than the Lasagna model. After all, in Java you also have Java modules that can easily call each other (and I got the impression that there is no real structure between all the different Java modules). For me, the Lasagna model seemed to be the result of a non-object oriented old code, while the Ravioli model seemed more modern, more object oriented.
Currently, I usually return to the Lasagna model, but with a built-in Ravioli model. It:
- The application is built using different layers, for example, in the Lasagna model
- But inside the layers, the code is still split between different modules that can access each other, for example, in the Ravioli model.
Some circular links may be difficult or impossible to delete. An example is the following: Suppose your application has a FileWriter class and a Debug class. The Debug class will need the FileWriter class, since it needs to write files with debugging information. On the other hand, the FileWriter class can also use the Debug class.
Note that the circular reference in this example may already lead to problems (the FileWriter class can call the Debug class when writing a string, but the Debug class uses the FileWriter class to write debugging information, the result is a stack overflow).
In this case, the problem can be easily solved without using the FileWriter class in the Debug class, but using the native iostreams (if you are developing in C ++). In other cases, the problem can be solved much more complicated.