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

前端 未结 4 1092
栀梦
栀梦 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<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.
    0 讨论(0)
  • 2021-02-05 07:53

    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.

    0 讨论(0)
  • 2021-02-05 07:54

    The behaviour that is on your entities should reflect the business model. What can be done to or by that entity is the business world should be sopmething that can be done to or by the entity class. For example:

    In an online shopping system, you can add a product to your cart. So the Cart class should look like this:

    public class Cart
    {
        //...
    
        public void AddProduct(Product product)
        {
            ...code to add product to cart.
        }
    }
    

    It could be argued that the methids should reflect the use cases.

    0 讨论(0)
  • 2021-02-05 07:58

    some behavior that i try to put into my domain, entities or value objects.

    validation before persistence. validation before transition into a new state. For example order aggregate root entity can validate its internal state and its aggregate children before going into state Sent. minimize get set properties and use value objects as much as you can. First it makes the model richer with behavior. the entities get more descriptive. second you more rarely put your entity into a invalid state if you must use value object methods like ApplyAdress method on a person entity which takes an Adress Value object as in parameter.

    what more... Info intelligence. use your entity and its value objects to control and restrict aggregate information. like personidentity can be a value object that handles the uniqeuness of a person. it incapsulate ssn, ssn algoritm, handle gender checksum on ssn etc.

    0 讨论(0)
提交回复
热议问题