DDD Aggregate Root / Repository Structure

最后都变了- 提交于 2021-02-08 13:52:52

问题


I am new to this, so my understanding is still flaky.

I have a Person model and an AccountType model in my project. Each person references an account type.

Now if my understanding is correct a Person is definitely an aggregate root, whereas the AccountType probably isn't as the entries in the account type table are going to be pretty much static and are certainly have no meaning outside of a Person.

However when I create a new person I need to set the account type, so it would seem I need a repository to access the account type to assign to the user, but the repository code I have only allows aggregate roots to be accessed.

What would be the correct way to structure this?


回答1:


I think that AccountType is another aggregate root which is referenced from the Person aggregate root. It's absolutely normal to have many simple aggregate roots, see Vaughn Vernon articles, see part 1, p. 5:

On one project for the financial derivatives sector using [Qi4j], Niclas [Hedhman] reported that his team was able to design approximately 70% of all aggregates with just a root entity containing some value-typed properties. The remaining 30% had just two to three total entities. This doesn't indicate that all domain models will have a 70/30 split. It does indicate that a high percentage of aggregates can be limited to a single entity, the root.

In your question it's not quite understood, what is the problem with accessing repositories to initialize the aggregate root's properties:

However when I create a new person I need to set the account type, so it would seem I need a repository to access the account type to assign to the user, but the repository code I have only allows aggregate roots to be accessed.

The initialization of the Person class should be handled by PersonFactory.

The PersonFactory is a service, so it can have reference to AccountTypeRepository to find a suitable AccountType instance and return a fully constructed Person instance of that type.

update: Also I'd like to add a note that referencing your AccountType by id works equally well. It's all matter of convenience, sometimes it's more convenient(only for displaying, not for modifying, of course) to access the references directly if you use GUI frameworks with rich data binding capabilities like WPF or Spring MVC so you can directly access this properties to display in View. If you are using the id approach, this may force you to create ViewModels (FormBeans) even for the simple Entities.


Regarding the lookup-based solution, it works well for very simple enum-like fields, I suppose that AccountType is something more complex than that and belongs to the knowledge level (see the discussion of the question).

Returning to the choice between aggregates and value object(also see this), it depends on the abstraction level and configuration capabilities of your information system. From the point of view of the Account class it may look like a value object, you can replace one AccountType with another: it will be just like switching between Color value objects, but from the point of the knowledge level your user may want to customize the behavior of the system for selected AccountType, for example change discounts for specific "Premium" accounts. So if you have the knowledge level, AccountType will be something with an identity which leads you to creating a separate repository.




回答2:


The most important thing is (assuming AccountType has an entity with an ID and is not a simple enum)...

Account Type and Person should only reference each other by ID.



来源:https://stackoverflow.com/questions/11842392/ddd-aggregate-root-repository-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!