I am working on a simulator that simulates patients, so specific processes can be validated in "virtual" patients, before testing real patients. The simulator is essentially a mathematical model that consists of multiple ordinary differential equations (ODE), which can be calculated using a numerical method. These mathematical models are calculated step by step, which means that you need the previously calculated values to calculate new values. These steps can be small or larger, the smaller the step, the better the result, but it will take longer to calculate.
At first the development went well, but gradually the simulator became a disaster, we introduced a second mathematical model and a second EDO solver. I had to work with the same "virtual" patients. But the second mathematical model required the patient to have some additional fields and the vector matrix of calculated values became slightly larger (from 7 entries per step to 10 entries). This worked, but now we are thinking of adding another mathematical model, which requires even more properties in a patient and the calculated values could not be stored in the same vector matrix, because the first 3 entries are for different values from the Other models. We are now contemplating leaving the first 3 0 / null entries and adding 3 entries at the end of the vector matrix for the newest model.
Here is our silly class diagram to show the problem:
The class diagram shows only 2 concrete models and 2 concrete solvers, but we need to add at least 1 more model. As you can see, the patient has 7 variables. The first model requires the first 5, the second required them all and the newest model requires only the last 4 (and 2 additional not yet added). Below is a schedule with "life events" of the patient that influence the calculated values of the patient. Below that is the vector matrix that has 10 entries. the first 7 are only used by the mathematical model X, the 10 are used by the Y model and the newer model would require adding an additional 3 at the end, and the first 3 would not be used by that model.
What is a design pattern that works here?
I tried using inheritance. The second model uses the first model as a base class, this works. But when a third model is added that does not need some values / functions, is that still the right way? In addition, the patient's problem still existed, because it would also need to be inherited or additional attributes would simply be added.
I also tried this, but I had the same problems as with inheritance.
Does anyone see a solution for this design problem?
Then there is a second problem
This problem is related to the creation of the simulator mentioned above. As you can see, patient creation is done through a CreatePatient () function in the simulator, which requires a list of patient values (varibale 1 to 7 in patients) that is growing since more model was added. And a schedule with "life events" that influence the values calculated by the patient.
The creation of the simulator, the schedule, the model and the solver is now done in a CLI and GUI project that refers to the Simulator project. There are 2 problems I see, the first one refers to the growing list of attributes / properties and the vector matrix of calculated values when adding a model. This makes it more difficult to create a patient. To solve this, the first problem addressed above that must be resolved first is my opinion. Second, creation is a bit weird now. The CLI requests a user file path that points to an .ini file with configuration for the simulator. This .ini file consists of a configuration such as the duration of the simulator, how large the step size should be (remember the models mentioned above and how they are resolved), if the patients should be exported, seeds. It also provides for each possible patient value (patient attribute / property) the range that this value can be, and you can also add a file path list to .ini files that contain coded patient values.
Therefore, one could say that I want 50 patients, then 25 .ini files are indicated in the .ini configuration file for the simulator and the rest of the patients will be generated using the specified value range. The same is done for the schedule that must be generated for each patient.
The problem I see with the above is that a patient is created through the simulator object after creation, but the patient's schedule is not. The reason why programming is not is because it is now generated in the CLI / GUI according to some configurations in the .ini file. Should these creations be done differently? Should the creation of a patient even be done through a simulator object? Should there be a factory method for each object (schedule, patient)?