I am working with an existing numerical model implemented in C++, and I don't have much of a background in software design. This model reads in many (~100) of structured text files, performs numerous calculations, and then spits out an answer. The current organization of the program is as follows:
- Main function creates a DataBox object, an instance of a data holder class, which has public variables for all the variables that are used in more than one step. DataBox has ~100 variables in it, including matrices, strings, maps, etc.
- Reads in the data and stores it in the DataBox.
calc1(&DataBox), stores the results in DataBox in the function, calls
calc2(&DataBox), etc. until done.
calcndepends on values from step 2 as well as calc1->calc(n-1), not just n-1. The same instance of DataBox is passed to each function.
This DataBox approach seems to have the many of the same disadvantages as using global variables. Although the DataBox doesn't pollute the global namespace, it can be difficult to determine where a DataBox member variable is first initialized, and where in the code it is possibly modified. It can also cause merge problems, as the merge can occur without conflicts, but then the program fails because a member of DataBox was modified without the other file knowing.
The obvious alternative to me is to explicitly pass the variables needed at each step rather than the DataBox, rather than the full DataBox, but this is annoying because each step can require lots of variables from prior steps, and we sometimes want to change which data is available. Is there a better alternative? One idea I had was to make all the DataBox variables private and then create only create getter functions, so that the data can be accessed easily, but not modified. However, it is not obvious to me how to control the context in which setter functions can be accessed.