Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD: What kinds of behavior should I put on a domain entity?

Tags:

My team tries very hard to stick to Domain Driven Design as an architectural strategy. But, most of the time, our domain entities are pretty anemic. We'd like to be putting more business/domain behavior on our domain entities.

For example, Active Record puts data access on the entity. We don't want that because we happily use the repository pattern for data access.

Also, we design our software to be SOLID (the five software design principles that Uncle Bob put together). So, it's important to us that we pay attention to single responsibility, open-closed, liskov, interface segregation, and dependency inversion while designing our entities.

So, what kinds of behavior should we include? What kinds should we stay away from?

like image 946
Byron Sommardahl Avatar asked Oct 16 '11 00:10

Byron Sommardahl


People also ask

How are entities related to Domain-Driven Design DDD )?

A domain entity in DDD must implement the domain logic or behavior related to the entity data (the object accessed in memory). For example, as part of an order entity class you must have business logic and operations implemented as methods for tasks such as adding an order item, data validation, and total calculation.

What is considered Domain-Driven Design pattern?

Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.

What are domain entities?

A domain entity is a unique, identifiable, and independent object within a domain. A domain is a collection of entities that share a common attribute. A domain entity is a unique, identifiable, and independent object within a domain. Domain entities can be physical or conceptual.

What are the strategies in extracting and formulating domain specific design principles?

Thus, we have developed three strategies for extracting and formulating domain-specific design principles: (1) analyze the best hand-designed visualizations in the domain, (2) examine prior research on the perception and cognition of visualizations, and, when necessary, (3) conduct new user studies that investigate how ...


2 Answers

It's been almost a year since I asked this question and I and my team have learned quite a lot since then. Here's how I would answer this question today:

The domain should represent (in code) what the business is or does (in real life). Domain entities, then, are the artifacts or actors found in that real-life business. What kind of behavior do those rea-life artifacts and actors have? All of it. In turn, what kind of behavior SHOULD domain entities have on them? All of it.

For instance, in real life, a manager can hire a new employee. The domain's representation of that should include entities like "manager" and "new employee". The manager is the actor, here.

//newEmployee comes from somewhere else... possibly the UI //someManagerId comes from the logged in user var manager = _repository.Get<Manager>(someManagerId); manager.Hire(newEmployee); 

So, the manager entity models/reflects the behavior of the real-life business, here. The alternative is to skip the manager entity as an actor, and push him off to the corner so a heavy-lifting "domain service" can do all the work... like this:

//newEmployeeService comes from somewhere else... possibly injected using IOC newEmployeeService.Create(newEmployee, someManagerId); 

In an anemic domain, you would use a domain service like this to create or hire an employee. It works, but it's not expressive and the behavior is not as discoverable. Who does what? Why is the manager required to create a new employee?


I think when I asked the question originally, I wanted to try to start including more behavior in my entities, but I really didn't know how without injecting services into my entities (for instance, with constructor injection). Since then, we've learned some new tricks and our team's entities are super-expressive. Here's, in a nutshell, what we are doing:

  1. We try to, when possible, use actor entities to express the person or thing that is performing the action.
  2. Actors have methods that express the actions they can perform
  3. When a service is needed, it is injected as an argument in the method where it is used.
  4. We fire domain events using BlingBag on every method on every domain entity to provide extensibility and give entities the ability to self-persist.
like image 192
Byron Sommardahl Avatar answered Oct 21 '22 06:10

Byron Sommardahl


If you have to ask what behaviour you should put on the domain entity then you probably don't need DDD. I'm trying to be helpful here, because I have had a lot of pain trying to fit DDD into a place it didn't belong.

DDD or even domain model are patterns that can be followed after it is discovered that the domain complexity is too high for any other pattern to work. So just CRUD is not suitable for DDD. From my understanding, DDD fits when you have a bounded context that contains complex business rules that need to be run before transitioning state for the aggregate root. So I would not include validation in the definition of complex.

The kind of behaviour that you want to put in your entities is intimately related to the business problem you are attempting to solve. The concern about persistence (repository etc) should come after (In fact, persistence might be in an workflow or event store).

Hope this helps.

like image 27
Davin Tryon Avatar answered Oct 21 '22 06:10

Davin Tryon