We're designing a major refactor in my company system's codebase. One of the refactor points, is the (actual) definition of the business logic/domain model. Right now, every repository in the codebase will just fetch every possible piece of data related to the entity, and to "optimize" it, everything is being fetched in arrays rather than objects (technically, key-value hashmaps, but in PHP they're called arrays).
Now, I'd like to introduce the actual use of model objects that encapsulate business logic (calling methods like businessObject.canTransitionToNextProcessPhase()
rather than doing a bunch of if/else
in a controller, resulting in 0 readability.
For the first part of this design, I'm identifying what relational data is a must-load for every entity. It can be easily identified when an entity is dependant. For example: an Entry
should always load the Category
and the User
(author). However, when you fetch an User
, you don't necessarily need to load all their entries, friends, Etc.
Now, in some particular cases, when loading a User
, you might want to load all their Entries
too. How to design a repository pattern that let's you load said relational data in those particular cases?
For instance take the method UserRepository@getById(int)
:
Should the method receive option parameters that let decide whether to load additional relationships other than the default ones? (i.e: ContactInfo
is default, the list of Entries
is additional).
Should it instead be configued in a chainable method like repo.alsoLoad('entries').getById(id)
? (however this feels as replicating the ORM's API, I think).
Please note the objective of this repository pattern design is not just a layer that covers the ORM unnecessarily. Methods will retrieve data based on business use cases: getAllInvoicesFromCurrentCycle()
rather than getAll(hashamp /* with 5 key/values to be passed directly to the ORM's where clause*/)
since the latter provides no benefit (nor readability) whatsoever (might as well just use the ORM directly).
I will update the question if more clarification is needed.
User[A](requiredData: Foo, category: A)
and then getUser[List[Category]]
orUser[List[CategoryId]]
or whatever else makes sense.