5

When following the standard service and repository patterns, should your repository contain a specific method for every database operation or should you just use the general methods, e.g. update? Take for example the following service method:

DisableUser(User user) {
    user.enabled = false;
    userRepo.update(user); // General user update method
}

This performs its changes on the user record, then requests the repo update the database by calling the general user update method.

Or should it be more specific, like:

DisableUser(User user) {
    userRepo.disable(user); // Specific operation, matching the service
}

Obviously this is a very simple example but I feel the conclusion affects the way I move forward with repository's in general and this same logic applies to many scenarios.

What further confuses me is that in the first case using the standard update method may be seen as inefficient, because it may update every column on the record, but I happen to be using Entity Framework so it will take care of checking what fields have changed and only updating the changed field for me. But should I be making that assumption from my service?

If I were to write an alternate plain sql implementation of the repository id have to update all fields there, or implement field change detection myself. So that part leans me towards the specific implementation, but with that I'm adding a lot more methods and perhaps it feels a bit unnecessary.

So in a nutshell, should your repo just have the standard methods, update, insert, findById, findAll, delete. Or should it have a method for every specific database operation, like stored procedures.

There's probably several other considerations that I'm not grasping. Any advice would be appreciated.

  • update(User) is worse than both disable(User) (specific, targeted) and update(Entity) (generic, reusable). – blubb Jun 9 '16 at 19:19
  • @blubb its update(Entity) under the hood :) I have the basic methods coming from a generic repository. – matthewrk Jun 10 '16 at 8:26
2

To provide a different perspective than the already existing answer I would say that it depends.

The generic one is more reusable, but the domain-specific one signals intent and better separates your domain model from the choice of persistance. If you do

var user = repo.GetUser(id); user.Enabled = false; repo.Update(user);

Then the repo has no real idea what it is doing (which can be a good thing from the reusability perspective). But you have also lost the possibility of remembering the intent of the operation.

If you do the domain-specific one:

repo.DisableUser(id);

First of all, maybe you can implement your repository more efficiently. You might not need to get the user to disable him - maybe you can just do an UPDATE and be done with it. Also, you know what you are doing, so you could choose to also add a good log message in an audit log or something similiar at the repository level. While you could still do audit logging with the more generic version you would get a generic "customer updated" entry instead of a domain specific "customer disabled" entry. This can in many cases be very nice and valuable.

This is more work though, which is why in general people will go with the generic solution because it is more generic and easier to implement. But dont disregard the domain-specific repository as unusable or bad, the answer is always it depends.

0

If you stick to the more general methods, update, insert, findById, findAll, delete, your code will likely be more re-usable. By this I mean that instead of writing a specific method for every scenario you will find that you can simply expose the more general methods and use those for the specific cases that are needed. For example, I might need to disable a user, for this I would call the update method. You might later have other interfaces that need to disable a user and you can again call the same update method instead of writing a whole new method to deal with that specific case. I've done a lot of work in SOA (Services Oriented Architecture) and can say the more generic you can keep things the easier you will find it to maintain good code. Eventually you might find your organization wants to move to a Service Bus to maintain all the various services. With more generic methods this transition will be much easier.

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.