I have a question regarding the repository design pattern. Let's say I have a datatype Foo
. In several places in my application, I must fetch a list of Foo
from a remote database. For example, let's say I need to fetch a list of trending Foo
s and somewhere else a list of the most recent Foo
s. In my mind I have two options:
- I could define two repository classes, one called
TrendingFoosRepository
which fetches from/foos/trending
and another calledRecentFoosRepository
which fetches from/foos/recent
. - However, since
TrendingFoosRepository
andRecentFoosRepository
do exactly the same thing just at different endpoints, I could define one repository class calledFoosRepository
which takes in anendpoint
argument, and instantiateFoosRepository('/foos/trending')
andFoosRepository('/foos/recents')
.
To me, the second option is more concise and reusable and is therefore preferable. However, something feels odd to me about passing in endpoints into a repository. Is this antipattern? If so, why and what is the alternative?
CodePudding user response:
It is possible to use enum
instead of magic strings.
enum Popularity {
TRENDING,
RECENTS
}
and use it as a parameter in your method:
FoosRepository(Popularity popularity)
In my view, using enum
is a little bit cleaner.
CodePudding user response:
Let's forget for a minute that we are talking about repositories.
So, you have described two options:
- Multiple separate classes with tiny difference between them
- A single, parameterizable class
Let's do a trade of ananlyzis
Multiple separate classes
Pros
- They can evolve separately
- A bug in one class will not affect others
- A n 1 variant can be independently introduced
Cons
- Might be code duplication
- Harder to maintain
- (Harder to find all usage/references)
Single, parameterizable class
Pros
- Single codebase which is multi purpose
- Single place to fix a "common" bug
- Might be easier to understand the system
Cons
- If it is too generic then it can harm legibility
- You might end up
- with a god class with too many responsibilities
- having too many parameters
- with a handful of branching logic depending on the parameter(s)
- In order to solve the previous issues you might split the code into multiple classes
So, if you choose
- multiple separate classes over single, parameterizable class then you prefer flexibility over code reusability
- single, parameterizable class over multiple separate classes then you prefer configurability over code evolvability
Whatever decision you make please add a comment to your solution to explain why did you choose X over Y or why did you exclude Y, Z during the evaluation of the problem space. This reasoning can't be read from the codebase.