Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository, Service or Domain object - where does logic belong?

Take this simple, contrived example:

UserRepository.GetAllUsers(); UserRepository.GetUserById();

Inevitably, I will have more complex "queries", such as:

//returns users where active=true, deleted=false, and confirmed = true
GetActiveUsers();

I'm having trouble determining where the responsibility of the repository ends. GetActiveUsers() represents a simple "query". Does it belong in the repository?

How about something that involves a bit of logic, such as:

//activate the user, set the activationCode to "used", etc.
ActivateUser(string activationCode);
like image 335
betitall Avatar asked Jun 04 '10 22:06

betitall


People also ask

Should domain objects have logic?

The theory states that the domain objects should encapsulate their behaviour and business logic. A model which contains only data and has its logic somewhere outside is called an "anemic domain model", which is a bad thing. Also, the domain should not perform data access.

Are repositories part of the domain?

Yes, repository implementations can definitely be a part of your domain model. In Domain Driven Design, for instance, the main objective when implementing a repository is to focus on the the perspective of the code that consumes the repository, not the code in the repository itself.

Does business logic go in domain layer?

The domain layer is responsible for encapsulating complex business logic, or simple business logic that is reused by multiple ViewModels. This layer is optional because not all apps will have these requirements. You should only use it when needed-for example, to handle complexity or favor reusability.

Where does business logic go in DDD?

According to DDD, business logic should be maintained in the Domain layer.


2 Answers

Repositories are responsible for the application-specific handling of sets of objects. This naturally covers queries as well as set modifications (insert/delete).

ActivateUser operates on a single object. That object needs to be retrieved, then modified. The repository is responsible for retrieving the object from the set; another class would be responsible for invoking the query and using the object.

like image 83
Bryan Watts Avatar answered Nov 07 '22 17:11

Bryan Watts


These are all excellent questions to be asking. Being able to determine which of these you should use comes down to your experience and the problem you are working on.

I would suggest reading a book such as Fowler's patterns of enterprise architecture. In this book he discusses the patterns you mention. Most importantly though he assigns each pattern a responsibility. For instance domain logic can be put in either the Service or Domain layers. There are pros and cons associated with each.

If I decide to use a Service layer I assign the layer the role of handling Transactions and Authorization. I like to keep it 'thin' and have no domain logic in there. It becomes an API for my application. I keep all business logic with the domain objects. This includes algorithms and validation for the object. The repository retrieves and persists the domain objects. This may be a one to one mapping between database columns and domain properties for simple systems.

I think GetAtcitveUsers is ok for the Repository. You wouldnt want to retrieve all users from the database and figure out which ones are active in the application as this would lead to poor performance. If ActivateUser has business logic as you suggest, then that logic belongs in the domain object. Persisting the change is the responsibility of the Repository layer.

Hope this helps.

like image 22
Joel Cunningham Avatar answered Nov 07 '22 19:11

Joel Cunningham