简体   繁体   中英

Should entity hold reference to repository?

Suppose we have class Home and we want to have collection of all Cats inside this home, but also we want to have general repository of Cats that has all the cats available in the world. Should Home hold the reference to specific repository (or maybe collection) of Cats , or should I just make another lookup in general repository?

From a domain-driven design perspective you shouldn't have one aggregate root (AR) instance contained in another AR instance and typically one also would not have a reference to a repository in any entity.

So if Home and Cat are both ARs then Home should contain only a list of Cat Ids or a list of value objects (VO) that each represent a cat, eg HomeCat that contains the Id and, perhaps, the Name . This also facilitates the persistence around the Home AR since the HomeRepository will be responsible for persistence of both Home and HomeCat .

I must admit that this is where an Entity such as Cat becomes somewhat of a weird thing when it is contained in more than one AR. However, you would still not have the cat repository in the home object but rather have the HomeRepository make use of the CatRepository when retrieving the relevant home instance.

As Java is based on references, you could keep two collections without any serious harm.

What you need is to assure is that every cat on your home is also in the "world". The problem here is if the cats on your home change a lot, you would need to make several lookups, so you should choose a data structure data enables this as fast as you need (i am thinking hashMaps..)

using two collections will enable you to find cats in your home as fast as you can do. however sync-ing the collections might be a problem. in this case you can think about the observer pattern: home observes the world, if a cat dies, it check if it was inside home, and deletes...

there is a lot of way to do what you asked, all you need to do is think about what is the operations with higher frequency, and your need in general. if the collections are small, so no problem on having one collection, with lookups to find the cats home...

It's hard to answer DDD questions with fictional domains (or at least very little information about it), since DDD is all about modeling the domain just the way it is and maintaining the integrity of it's invariants.

As far as I can tell, you do not have any invariant that applies to the relationship between Home and Cat , therefore you do not need a collection of Cat objects within Home 's consistency boundary. You could simply have two aggregate roots ( Home and Cat ) and Cat would reference it's Home by identity .

You can use the CatRepository to query all cats from a specific home or all cats independently of their home.

It's important not to put artificial constraints in the model. For instance, if you hold a collection of Cat identities inside Home for no other reason than maintaining the relationship, then you are limiting the scalability of your system: two simultaneous transactions trying to associate a new Cat to the same Home will fail with a concurrency exception for no reason (assuming optimistic concurrency).

If Cat needs to be an aggregate root of its own aggregate accessible by a CatRepository , then it should not be included in the Home aggregate. Your Home entity should reference the associated Cat entities by identity and not by reference.

This is a question of aggregate design and requires a closer look at your domain and how you need to use your entities. One question you could ask yourself is "if I delete Home , should all Cat entities be deleted as well?" Do not put too much emphasis on this question. There are other important factors that need to be considered.

Vaughn Vernon covers this topic in his three-part PDF series Effective Aggregate Design .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM