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

前端 未结 4 1091
栀梦
栀梦 2021-02-05 07:34

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 mor

4条回答
  •  北恋
    北恋 (楼主)
    2021-02-05 07:46

    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(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.

提交回复
热议问题