Think about a collection of one related type on another, such as Customer -> Accounts + Account -> Customers. In banking, it is possible for one customer to have many accounts, and for each account to have many customers.
OOP will let you express this kind of problem from a data modeling perspective (List<T> on each type), but from a serialization and dependency perspective you have to pick a "winner". In banking, it is unclear which type should be king.
The relational approach is to use a join table. Model the actual relationship itself and its relevant attributes (role on the account, beneficiary %, etc). This also handles any arbitrary graph of accounts and customers, assuming you are using a modern database engine that supports with recursive & cycle keywords.
ORMs will blow up on this kind of thing without special handling.
> OOP will let you express this kind of problem from a data modeling perspective (List<T> on each type), but from a serialization and dependency perspective you have to pick a "winner". In banking, it is unclear which type should be king.
Serialisation is not necessarily a big deal, just pick one and refer back to it — check out PRINT-CIRCLE, Sharpsign Equal-Sign and Sharpsign Sharpsign in Common Lisp.
For dependencies, I think this only matters with strong type systems which don’t support forward declarations, or which lack null references/empty containers (if the language does support that, just create one object without any references, create the second, then add the second to the first).
FHIR, an international standard for medical data, is a great example here. The circular types get so gnarly that I've personally managed to infinite-recursion the TypeScript compiler. We even managed to get 45min builds followed by a timeout by sneezing wrong.
The tldr is that you can have things that belong to things that belong to things that end up belonging to the original thing after a very very long inscrutable chain of pointers. Essentially a graph.
Maybe like how having a handle back to something can be a parent-child relationship or can imply that the child owns the parent, especially if the lifetime is extended by the ownership (e.g. shared pointer).
OOP will let you express this kind of problem from a data modeling perspective (List<T> on each type), but from a serialization and dependency perspective you have to pick a "winner". In banking, it is unclear which type should be king.
The relational approach is to use a join table. Model the actual relationship itself and its relevant attributes (role on the account, beneficiary %, etc). This also handles any arbitrary graph of accounts and customers, assuming you are using a modern database engine that supports with recursive & cycle keywords.
ORMs will blow up on this kind of thing without special handling.