2

We're using an internally-built ORM. Each table is represented by a Model class, which inherits from a base model class that has a handful of methods like GetAll, GetWhere (to get rows with specified column values), GetFirstWhere, etc. to access data from the table. There's a question of whether these methods should be protected (so that any database access needs to call a public wrapper method for the exact query) or public methods (so that code anywhere can call GetAll, GetWhere, etc.)

I see some pros and cons for both sides. Which style would be considered best practice and more maintainable?

Protected

Pros: it's easy to see all queries against a table, just open the Model file. This could be useful for checking whether the table is indexed properly, etc.

Cons: extra work and cognitive overhead for every data access. I now have to check whether a query method already exists and create it if not; I have to look up method names, which tend to be specific like "GetThisThingByIDAndName"; also, if I want to change a query, I need to make sure nothing else was using that method or create a new method. Many of these queries are only ever going to be used once, and in practice there end up being tons of these methods whose names don't always clarify exactly what the method does.

Public

Pros: the standardized data access interface allows developers to easily memorize the few data access methods and use them consistently across tables, which makes development faster and simpler. Also, they can make changes directly where the query is taking place without breaking something elsewhere in the codebase.

Cons: requires a search to find all queries against a table. If not careful, there could be some duplication.

  • 3
    The fact, that you are mixing the data model with data access is worse problem than whenever the data access should be public and protected. And it baffles me people still implement their own ORM, considering there are thousand and one existing solutions out there. – Euphoric Aug 12 '14 at 6:13
3

You should use Repository pattern (domain driven design) that is decoupling business logic from infrastructure. Details (implementation) should depend upon abstractions, not other way.

Repository pattern let you change underlying persistence storage (database) whenever you want, even in runtime and makes code much easier to test.

  • An example would make your answer a better one. From my point of view, the most valuable benefit of a Repository abstraction or service layer is that you expose methods that do something, rather than simple pass-through methods that merely return business objects. – Robert Harvey Aug 12 '14 at 17:26
  • What do you mean, that they "do something"? In ddd it just return aggregate roots, business logic should be outside of repository according to books. – Rafał Łużyński Aug 12 '14 at 18:26
  • Why not just let the ORM do that? – Robert Harvey Aug 12 '14 at 18:28
  • 1
    ORM is returning it's own objects, how can I make Django ORM/hibernate/doctrine return aggregate roots? – Rafał Łużyński Aug 12 '14 at 18:35
  • Ah, I see what you're saying. stackoverflow.com/a/1958722 – Robert Harvey Aug 12 '14 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.