Question

While implementing a find (or search) method in a repository class, is is better to accept a domain model or is it better to implement specific find methods?

For example we have a Person class with the attributes name, id.

In the repository we could have a find method that accepts a person as a parameter. That method will use the given model to search for an existing person.

The other approach is to implement a find method per attribute (find_by_name, find_by_id).

Since I will be implementing this in Python I could also implement a method accepting keywords. This will resemble the accept-a-model approach: find(name='harry')

As a side question, when the find method concerns an indexed value (id), is it better to use get_by_id() (which implies indexes) or find_by_id() (which is more abstract).

Was it helpful?

Solution 2

Use findBy(attribute) is preferrable in semantics and more meaningfule if there is not many specific query requirements.

 personRepository.find_by_name(name); //is easy to read
 personRepository.find_by_age(age); //
 personRepository.find(person); //this one is at odds and confused

But if there are too many specific query methods on the repository, it's also a pain. In this case, you need a criteria. Pretty much the same way you use your find_by_person now, but more natural in semantics.

 criteria.nameEq = 'hippoom';
 personRepository.findBy(criteria);

 criteria.worksFor = 'XXX company';
 criteria.ageGt = 25
 personRepository.findBy(criteria);

OTHER TIPS

Personally I would implement specific find methods. A repository is a collection-like abstraction of the persistence mechanism and its interface should be written in the semantics of your domain.

Although queries like find_by_name or find_by_id are valid, very often one would need queries of the type find_vip_persons which could be a combination of several properties of the Person aggregate root (e.g. salary > 10000 & age > 21). Especially in cases like these I would avoid a generic query method, since the domain logic (i.e. what makes a person a VIP) could easily become scattered everywhere in your code base.

Although I'm not very familiar with Pythons keyword arguments and could be wrong here, I would assume that the 'accept-a-model approach' you're considering doesn't allow for more complex conditions like the VIP example from above anyway (i.e. comparison operators).

If you want use a generic repository interface and reuse queries at different locations in the domain, then you should have a look at the 'Specification Pattern'.

Regarding your 'Find vs. Get' question I'd say it doesn't really matter. I would probably use 'Query' instead, but that's just a matter of personal preference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top