Question about OO programming, functional programming, NoSQL, SQL databases and software architecture
I am a mid-level self-taught programmer and am dying to get an answer to this general question about structuring my apps. Having no degree in computer science and only a few programmer friends, I have not been able to get a clear idea of how "correct" or "better" it is to deal with this type of problem.
This type of pattern appears everywhere in my current application and I'm not sure what I should do. The reason is:
I have a database model that is a model of type "container" or "parent", which contains many elements that refer to it. For this, we can use a model "Road", which represents a driver's route for the day.
He has fields like:
- Created time - Assigned driver - Notes - isCompleted - isReconciled - serviceCount
I have another database model that is the main "child" that refers to the "parent", in this case, the road. In this case, it is a "service" which represents each of the stops that the driver must perform as part of his itinerary of the day. All services of the relevant route have a reference to the route. The relevant fields of a service are:
- Route <- id referring to the 'parent' model - Notes - isCompleted - isReconciled
In many of these cases, it happens that, if you change a service (the child), you want to update a "higher level" or a "summary value" in the route (the parent).
- When all services are 'complete', update the route to be 'complete' - When all services are 'reconciled', update the route to be 'reconciled' - If you add a service to a route, update the 'service count' on the route
Currently, to handle these kinds of things, I have functions that work normally after each relevant change of a service. This would call something like updateRouteAfterServiceIsModified. It simply updates the route after any changes to the services, to update these summary values.
However, I understand that if I took a more object-oriented approach, I might have some kind of post-backup hook or something similar, so if you change a service, the route will be updated. I can see how this could improve the code organization, but I can also see how it could get more complicated.
One of the things I've been thinking about is never calculating these summary values when it comes to service changes, because they can be determined on the fly, as far as they are inferred properties or calculable. For example:
- To know if the route is complete, just check if all the services are complete - To know if the route is reconciled, just check if all the services are reconciled - To know the route count, simply count the number of services, as at the time you need to know
The problem in calculating this data on the fly for me is that I will usually have a list of the 'parent' item. (routes), and I want to do something like Sort by these calculated fields. If the value is not saved on the parent, I have to compute it on the fly to sort the list.
I use Mongo as a data store and aggregations on foreign fields get complicated quite quickly, as well as other relevant calculations to perform the desired sorting. This seems to be an overly complex and potentially non-evolving solution. But I'm not an expert in Mongo, so I'm not sure.
I have never used SQL, for example. PostgreSQL; I have a friend who suggested that this sort of thing is a lot easier in Postgres. Perhaps it is possible that the "normal" thing to do in this situation with Postgres never saves these summary values on the parent, and calculates them simply at the time of sorting, and that Postgres does it effectively. Perhaps it is true that the code does not become rough and that it evolves well. If that's the case, although the application is primarily built, I'd consider switching to Postgres - but I've just never tried it.
In summary, I think there can be 4 possible solutions to this type of problem:
Use a functional programming style and encapsulate or call functions appropriately for "child" mutations to record all desired data on the appropriate "parent" template.
Use an object-oriented programming style to handle these summary / calculated values by saving them to the "parent" model.
It is not necessary to save these values, to calculate them on the fly, Mongo is fine, the aggregations can be very powerful, you just have to master them and build abstractions where it would be useful or simplify your code.
There is no need to save these values, and the key to this process is the use of SQL, which makes sorting easier based on a computed value for a foreign field, so you have to switch over because this makes this type of process trivial.
I do not know if there is a "correct" approach to this, but my experience seems to me to be so common that I would have thought that there would be a consensus within the development community about what I should do.
Any help would be greatly appreciated, even if it was simply to direct me to resources that could be useful!